最近咱们的一个项目,因为一次请求知足条件数据库的数据量过于大,因此页面的访问非常缓慢,如今在作优化就是一次只请求一页数据过来,当用户点击下一页或者上一页或者进入指定的页就会当即去请求这样会很快,能够极大的提升速度。mysql
因为咱们的数据库用的是mysql,故而通常使用的limit start,count来进行分页请求,这样的请求看似是极好的,可是当咱们的数据量很大的时候,到达几百万的状况下,找最后一页的数据的的速率会降低,就是start 数值越大,咱们的效率就月底。sql
1统计全部的条数 . 数据库
被咱们的cpu_statistic表有3百多万条数据,dom
终端在线统计表里面没有数据优化
能够看到数据量越大,统计的时间就越长(统计所得,三百多万条,耗时0.7秒,五百多万条,耗时就达到了10秒多)。spa
2. limit分页优化code
1). 查询前三条数据,速度极快:排序
这个是根据id降序排列索引
这个是没有排序,默认是升序的terminal
能够看获得查询的数据仍是极快的,
2).查询倒数两条数据,就能够看获得最起码要花掉1秒的时间
首先咱们能够看获得,上图有两种方法,
第一种方法,最原始的limit start,count 花了1.78秒,能够看到随着start的增大时间变长了,缘由是mysql要扫描前3407870条数据及之后的三天,而后把前3407870条记录给抛弃了。
第二种方法,直接查找从哪儿开始开始的3条记录,id直接判断,调过了所有扫描的过程,因此更快,且随着数据增加速度会更快
下面还有第三种方法,内链接,运行效果以下:
能够看得出效果也是比最原始的limit start,count变快了,可是效果比第二种方法慢一点,但也差不了多少,因此我推荐使用第二种方法。
总结下来就是优化limit有两种方法:
子查询
内链接
3.分页的limit以前若是不加上order by语句,查询时间就会缩短。
能够看获得每条语句比不加order by要快上400多毫秒。
4.详细的解释分页优化子查询的语句的意思(新手能够不太懂,能够看看,有经验的能够略去)
不少新手可能不理解这个句子,下面咱们就一步一步的解释这个句子
查询知足条件的全部的数据安装id逆序排列
select * from terminal_online_statistic WHERE domain_moid = 'dcb80871-372b-4617-b329-9aafe6f78acb' && statistic_time BETWEEN '2015-08-04 10:57:48' AND '2015-08-04 14:57:49' order by id desc;
运行结果为:
而后咱们去前几条的l原始imit语句
select * from terminal_online_statistic WHERE domain_moid = 'dcb80871-372b-4617-b329-9aafe6f78acb' && statistic_time BETWEEN '2015-08-04 10:57:48' AND '2015-08-04 14:57:49' order by id desc limit 0,3
效果以下:
优化的limit语句不少人可能刚开始写的以下.
select * from terminal_online_statistic where id<=(select id from terminal_online_statistic WHERE domain_moid = 'dcb80871-372b-4617-b329-9aafe6f78acb' && statistic_time BETWEEN '2015-08-04 10:57:48' AND '2015-08-04 14:57:49' order by id desc limit 0,1) order by id desc limit 3.
运行结果以下:
能够看到不知足条件的也运行出来了。
缘由以下:咱们子查询的语句作了筛选,知足其第一条的id为49,可是咱们外面的查询没有作筛选,致使外面是查询全部的id<49的数据,而后逆序排列,而后之显示3条。
外层的也要作筛选,正确的语句以下:
select * from terminal_online_statistic where domain_moid = 'dcb80871-372b-4617-b329-9aafe6f78acb' && statistic_time BETWEEN '2015-08-04 10:57:48' AND '2015-08-04 14:57:49' && id<=(select id from terminal_online_statistic WHERE domain_moid = 'dcb80871-372b-4617-b329-9aafe6f78acb' && statistic_time BETWEEN '2015-08-04 10:57:48' AND '2015-08-04 14:57:49' order by id desc limit 0,1) order by id desc limit 3
正确的结果与原始的limit分页语句如出一辙。
------------------后面更新----------------
以前虽然总结了这篇文章,可是其实一直没有理解,为何子查询和内连接会比较快了,缘由在于,第一种查询。回表的次数比较多,须要根据ID查询出基本信息,会回表3407870+3次,可是换成子查询和内链接以后,第一次查询的时候,直接返回索引的ID,而后查询出知足条件的出来后,只回表3次。因此效率高