Mysql基础篇-35-limit的优化

本文探讨了MySQL在处理大数据量分页查询时的效率问题,特别是使用`LIMIT`语句随着页码增加导致的性能下降。提出了通过避免`LIMIT offset, size`方式,改用获取特定ID后再`LIMIT size`的方法,以及利用覆盖索引来优化查询。同时,文章还对比了`BETWEEN`和`>下界值 AND <上界值`的区别,并提供了针对不同数据规模的优化策略。
摘要由CSDN通过智能技术生成

1. 背景

mysql大数据量使用limit分页,随着页码的增大,查询效率越低下。
当一个表数据有几百万的数据的时候成了问题!
如 select * from table limit 0,10 这个没有问题 当 limit 200000,10 的时候数据读取就很慢

原因本质:

  1. limit语句的查询时间与起始记录(offset)的位置成正比
  2. mysql的limit语句是很方便,但是对记录很多:百万,千万级别的表并不适合直接使用。
    例如: limit10000,20的意思扫描满足条件的10020行,扔掉前面的10000行,返回最后的20行,问题就在这里。 ​ LIMIT 2000000, 30 扫描了200万+ 30行,怪不得慢的都堵死了,甚至会导致磁盘io 100%消耗。 ​ 但是: limit 30 这样的语句仅仅扫描30行。

2. 优化:

2.1 使用 limit offset 而不是 limit offset,size

不是直接使用limit,而是首先获取到offset的id然后直接使用limit size来获取数据

2.1.1 limit offset,size(含子查询)

几十万数据可以使用这个,但是实战中可以直接将上一页的最后一条记录id 传入到下一页查询中作为起点使用,从而节省子查询的消耗

2.1.2 仅仅使用 id<max and limit size 或者 使用 min<=id<=max

千万级数据不建议使用覆合索引+join ,耗cpu/IO 极其严重

select * from order_table where company_id = 1 and mark =0 and id <=82543981 order by id desc limit 200000;

2.2 利用表的覆盖索引来加速分页查询 覆盖索引 + join

覆盖索引:
就是select 的数据列只用从索引中就能获得,不必读取数据行。mysql 可以利用索引返回select列表中的字段,而不必根据索引再次读取数据文件,换句话说:查询列要被所创建的索引覆盖

其中覆盖索引获取起始id :select id from order_table where xxx limit 2600000 ,1; 的耗时会随着offset 的增加而增加。此种方式在查询前200万左右的数据时基本能在10s左右搞定,但是要查询 500万-600万这区间数据时覆盖索引的耗时显著提升。

3. between and 和 大于小于的区别

  • 表达式 between 下界值 and 上界值
    • 限定"表达式"的值介于"下界值"到"上界值"之间的所有值,并且包含"下界值"和"上界值";
  • 表达式 >下界值 and 表达式<上界值
    • 限定"表达式"的值介于"下界值"到"上界值"之间的所有值,但是不包含"下界值"和"上界值"。

两者比较接近,区别在于前者包含边界值,而后者则不包含边界值

  • 表达式 between 下界值 and 上界值
    等价于
    表达式 >=下界值 and 表达式<=上界值
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Alan0517

感谢您的鼓励与支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值