MYSQL百万数据查询优化

文章分析了深度分页查询中的性能瓶颈,提出范围查询、子查询、延迟关联和覆盖索引的优化方法。范围分页在连续ID情况下显著提高效率,而子查询和延迟关联则通过减少回表次数加速查询。覆盖索引避免了二次查询,减少IO操作,尤其在InnoDB表中效果明显。
摘要由CSDN通过智能技术生成

1. 查询现象


在查询第100000条记录之后的10条时,耗费时间:0.227s
![[Pasted image 20240326142128.png]]

在查询第200000条记录之后的10条时,耗费时间:0.251s
![[Pasted image 20240326142221.png]]

在查询第500000条记录之后的10条时,耗费时间:0.916s
![[Pasted image 20240326142249.png]]

在查询第800000条记录之后的10条时,耗费时间:1.639s
![[Pasted image 20240326142320.png]]

在查询第1000000条记录之后的10条时,耗费时间:2.038s
![[Pasted image 20240326142433.png]]

以上叫做深度分页,即查询偏移量过大的场景,这会导致查询性能较低

2. 优化建议


范围查询

当Id保持连续性时,可以通过对id进行范围分页,这种优化方式限制比较大,一般项目的ID没办法保证完全连续

SELECT * FROM confirm_order where id >1772450156306894849 LIMIT 10

当在查询1000000条数据之后的数据时,根据id进行范围分页,耗费时间为0s
![[Pasted image 20240326143919.png]]

子查询
由于我们需要第1000000条数据之后的10条数据,那么我们可以先找到第1000000条数据对应的id,根据这个id再去过滤并limit
这种方法只适用于id是正序的

SELECT * FROM confirm_order where id >(SELECT id FROM confirm_order ORDER BY id LIMIT 1000000,1) LIMIT 10

当在查询1000000条数据之后的数据时,根据id进行范围分页,耗费时间为1.632s,时间上比直接查询会快一点
![[Pasted image 20240326144411.png]]

延迟关联
延迟关联的优化思路和子查询的优化思路差不多,都是把条件转移到主键索引树上,减少回表的次数。不同的是,延迟关联使用了INNER JOIN(内连接)

SELECT c.* FROM confirm_order c,
(SELECT id FROM confirm_order LIMIT 1000000,10) d
WHERE c.id=d.id;

另外一种写法;(SELECT id FROM confirm_order LIMIT 1000000,10) d 相当于子查询

SELECT c.* FROM confirm_order c
INNER JOIN (SELECT id FROM confirm_order LIMIT 1000000,10) d
WHERE c.id=d.id;

当在查询1000000条数据之后的数据时,耗费时间为0.496s
![[Pasted image 20240326145428.png]]

覆盖索引
索引中已经保存了所有要查询的字段

覆盖索引的好处:

  • 避免InnoDB表进行索引的二次查询,也就是回表操作:InnoDB是以聚集索引的顺寻来存储的,对于InnoDB来说,二级索引在叶子节点中所保存的是行的主键信息,也就是说,在第一次索引时,我们找到了包含了主键信息的叶子节点,但是在该叶子节点中只保存了主键信息,所以需要根据主键信息进行第二次索引,这种索引也叫做二级索引/辅助索引,所以当索引中已经有了我们需要查询的值时,就不需要进行第二次回表查询,减少了IO操作,提高了查询效率。
  • 可以把随机IO变成顺序IO加快查询效率: 由于覆盖索引是按键值的顺序存储的,对于 IO 密集型的范围查找来说,对比随机从磁盘读取每一行的数据 IO 要少的多,因此利用覆盖索引在访问时也可以把磁盘的随机读取的 IO 转变成索引查找的顺序 IO。
SELECT id,member_id,train_code FROM confirm_order ORDER BY id LIMIT 1000000,10

当在查询1000000条数据之后的数据时,耗费时间为1.61s,当索引中属性越少,查询时间越少,不过差距并不是很大
![[Pasted image 20240326151454.png]]

  • 23
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL百万数据查询优化是提高数据库性能的重要步骤。下面是一些建议: 1. 索引优化:通过合理的索引设计,能够加快查询速度。对于经常作为查询条件的列,添加索引能够提高查询效率。 2. 分页查询优化:对于大数据量的查询结果,可以使用分页查询来避免一次性加载所有数据。通过设置合理的分页大小,可以加快查询速度。 3. 使用合适的存储引擎:MySQL支持多种存储引擎,如InnoDB、MyISAM等。根据实际应用需求选择合适的存储引擎可以提高查询性能。 4. 查询语句优化:通过合理的查询语句设计,能够减少不必要的数据查询和计算,加快查询速度。例如,避免使用SELECT *查询所有列,只查询需要的列。 5. 分区表:对于大数据量的表,可以考虑使用分区表来提高查询性能。通过将表按照某个列进行分区,可以将数据分散存储在多个物理文件中,提高查询效率。 6. 调整内存和缓存配置:根据实际硬件情况和数据库负载,合理配置MySQL的内存和缓存参数,如缓存大小、连接池大小等,以提高数据库性能。 7. 查询计划优化:通过对查询执行计划进行分析,可以找出查询中存在的性能瓶颈,并对其进行优化。例如,添加合适的索引、调整查询语句等。 8. 数据库分片:对于超大规模的数据量,可以考虑将数据库分片存储在多个服务器上,通过分片查询来提高查询性能。 总之,针对百万数据查询优化,需要综合考虑索引设计、分页查询、存储引擎选择、查询语句优化、分区表、内存和缓存配置、查询计划优化以及数据库分片等多个方面。不同的应用场景可能有不同的优化策略,需要结合实际情况进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值