mysql大数据量分页查询优化总结

mysql大数据量分页查询优化总结

大家好,又见面了,我是全栈君。

Mysql的分页查询十分简单,但是当数据量大的时候一般的分页就吃不消了。

传统分页查询:SELECT c1,c2,cn… FROM table LIMIT n,m

MySQL的limit工作原理就是先读取前面n条记录,然后抛弃前n条,读后面m条想要的,所以n越大,偏移量越大,性能就越差。

1)limit语句的查询时间与起始记录的位置成正比
2)mysql的limit语句是很方便,但是对记录很多的表并不适合直接使用。

推荐分页查询方法:

1、尽量给出查询的大致范围

利用表的覆盖索引来加速分页查询
我们都知道,利用了索引查询的语句中如果只包含了那个索引列(覆盖索引:索引的数据覆盖了需要查询的所有数据),那么这种情况会查询很快。
因为利用索引查找有优化算法,且数据就在查询索引上面,不用再去找相关的数据地址了,这样节省了很多时间。另外Mysql中也有相关的索引缓存,在并发高的时候利用缓存就效果更好了。
在我们的例子中,我们知道id字段是主键,自然就包含了默认的主键索引。现在让我们看看利用覆盖索引的查询效果如何:

之前,我们取最后一页记录的时间

select * from product limit 866613, 20   37.44秒

这次我们查询最后一页的数据(利用覆盖索引,只包含id列),如下:

select id from product limit 866613, 20 0.2秒

相对于查询了所有列的37.44秒,提升了大概100多倍的速度
那么如果我们也要查询所有列,有两种方法,一种是id>=的形式,另一种就是利用join,看下实际情况:

SELECT * FROM product WHERE ID > =(select id from product limit 866613, 1) limit 20
查询时间为0.2秒,简直是一个质的飞跃

另一种写法

SELECT * FROM product a JOIN (select id from product limit 866613, 20) b ON a.ID = b.id  

*统配符号在实际查询的中不应该使用,应该指明相应的属性,效率更好
其实两者用的都是一个原理,所以效果也差不多.

SELECT c1,c2,cn... FROM table WHERE id>=20000 LIMIT 10;

2、子查询法(在方法1基础上改进的)

SELECT c1,c2,cn... FROM table WHERE id>=
(
    SELECT id FROM table LIMIT 20000,1
)
LIMIT 10;

3、 第一步用用程序读取出ID,然后再用IN方法读取所需记录

程序读ID:

SELECT id FROM table LIMIT 20000, 10;
SELECT c1, c2, cn .. . FROM table WHERE id IN (id1, id2, idn.. .)

4.高性能MySQL一书中提到的只读索引方法(sql语句相比前三种复杂)

  一般表中经常作为条件查询的列都会建立索引,例如如下查询

    Sql代码  优化前

SELECT id, content  FROM tb_chat ORDER BY create_time DESC LIMIT 24000, 20;

Sql代码   优化后

SELECT id, content FROM tb_chat   
INNER JOIN (  
    SELECT id FROM tb_chat  
    ORDER BY create_time LIMIT 24000, 20  
    ) AS page USING(id);  

 这样当前查询页的内容就只会在索引中进行,当得到当前页的id再统一通过一个INNER JOIN得到最终要得到的数据详情,避免了对大量数据详情进行操作的消耗。当然JOIN操作也可以通过子查询实现,不过书中介绍5.6之前版本的mysql相比子查询还是优先使用JOIN。

对上一个sql继续优化改进,当有查询条件分页时,一定要确保有数据是在limit后面的条件里,正常有输入条件检索查询应该是limit 0, 10   我写的是limit 15000,20只是为了测试,因为符合该条件的数据只有1万5千多个,不然超出这个数就查不到数据了,切记。

SELECT id, content,c.z_type FROM tb_chat c
INNER JOIN (  
    SELECT id,z_type FROM tb_chat WHERE z_type='1'
    ORDER BY create_time LIMIT 15000, 20  
) AS page USING(id);  

等同于:

SELECT c.id, c.content,c.z_type FROM tb_chat c
INNER JOIN (  
    SELECT id,z_type FROM tb_chat WHERE z_type='1'
    ORDER BY create_time LIMIT 15000, 20  
) AS p ON c.id=p.id; 

个人觉得此方法更为通用,而且经过我的测试,发现表中总数据只有3万条数据时两个sql语句的执行时间竟然相差4倍,优化前的sql执行需要120ms,而优化后的sql需要30ms。

参考:https://www.cnblogs.com/shihaiming/p/6307018.html

https://blog.csdn.net/u011687186/article/details/70213024

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/111503.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长

相关推荐

  • CAS算法的理解及应用「建议收藏」

    CAS算法的理解及应用「建议收藏」应用原子操作类,例如AtomicInteger,AtomicBoolean …适用于并发量较小,多cpu情况下;Java中有许多线程安全类,比如线程安全的集合类。从Java5开始,在java.util.concurrent包下提供了大量支持高效并发访问的集合接口和实现类。如:ConcurrentMap、ConcurrentLinkedQueue等线程安全集合。引入问题那么问题来了,这些线程安全类的底层是怎么保证线程安全的,你可能会想到是不是使用同步代码锁synchronized?引入概念这些线

    2022年8月9日
  • 二叉树的实现

    二叉树的实现

    2021年10月6日
  • stat函数讲解_strcat函数

    stat函数讲解_strcat函数stat函数讲解表头文件:   #include<sys/stat.h>            #include<unistd.h>定义函数:   intstat(constchar*file_name,structstat*buf);函数说明:  &nbs

    2022年8月21日
  • Excel和CSV格式文件的不同之处

    Excel和CSV格式文件的不同之处Excel和CSV格式文件的不同之处来源:https://www.guru99.com/excel-vs-csv.htmlExcelCSV这是一个二进制文件,它保存有关工作簿中所有工作表的信息CSV代表CommaSeparatedValues。这是一个纯文本格式,用逗号分隔一系列值

    2022年7月21日
  • sqlserver将截断字符串或二进制数据_达梦数据库字符串截断

    sqlserver将截断字符串或二进制数据_达梦数据库字符串截断报的是下面这个错误:原因:在设计表时字段长度给的太小可以查看一下自己数据库中的字段的长度,看是否符合自己需要的长度怎么解决?1)将表中数据类型长度扩大2)减少插入的字符串

    2022年8月31日
  • Vuex入门(3)—— getters,mapGetters,…mapGetters详解[通俗易懂]

    Vuex入门(3)—— getters,mapGetters,…mapGetters详解[通俗易懂]Vuex提供了state这样的状态统一管理树,你可以在vue中用computed计算属性接收这些公共状态,以便使用,当然你也可以在接收原值的基础上对这个值做出一些改造,如computed:{sex:function(){returnthis.$store.state.sex+’加个字符串,算是改造’}}但是如果你的其他组件也要使用这…

    2022年4月27日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号