mysql-深分页优化
【摘要】 可能大部分人都没遇到过limit的性能问题,其实mysql的limit 页码值越大,执行的时间就越长。对于一些大容量的表可能就会存在性能问题。limit深分页为什么会变慢?这个主要是limit offset,size 不是跳过offset行,取N行,而是获取offset + N行,然后社区offset行。具体limit的SQL执行流程如下:通过普通的索引树,过滤业务筛选条件,找到满足的记录I...
可能大部分人都没遇到过limit的性能问题,其实mysql的limit 页码值越大,执行的时间就越长。对于一些大容量的表可能就会存在性能问题。
limit深分页为什么会变慢?
这个主要是limit offset,size 不是跳过offset行,取N行,而是获取offset + N行,然后社区offset行。
具体limit的SQL执行流程如下:
- 通过普通的索引树,过滤业务筛选条件,找到满足的记录ID
- 通过ID,回到主键索引树,找到满足记录的行,然后取出展示的列(回表)
- 扫描满足条件的offset+size行,然后舍去前offset行,返回。
其中需要注意的就是回表,也是产生性能问题的关键,当深分页的时候,需要取出的列越多,回表的次数越多,所以越慢。
常见优化策略
优化策略核心就是减少回表次数。
子查询或延迟关联
子查询和延迟关联原理都是一样的,通过查询出符合的数据ID,通过ID索引查询代替回表操作
- 子查询:
select id,name,balance FROM account where id >= (select a.id from account a where a.update_time >= '2020-09-19' limit 100000, 1) LIMIT 10;
- 延迟查询:
SELECT acct1.id,acct1.name,acct1.balance FROM account acct1 INNER JOIN (SELECT a.id FROM account a WHERE a.update_time >= '2020-09-19' ORDER BY a.update_time LIMIT 100000, 10) AS acct2 on acct1.id= acct2.id;
回表次数都是10次。
标签记录法
标签记录法需要有前置条件,子查询是通过自己查询第1000000行,而标签记录法的优化,则需要查询以前,就已经知道了第100000行的ID是什么,则此时直接走ID索引即可。
select id,name,balance FROM account where id > 100000 order by id limit 10;
覆盖索引
索引中已经包含了所有需要获取的字段的查询方式称为覆盖索引。
回表的目的就是获取索引以外的数据列,如果索引中已经包含了需要的数据,则不再需要进行回表操作,前提是需要查询的列为覆盖索引。
# 如果只需要查询 id, code, type 这三列,可建立 code 和 type 的覆盖索引
SELECT id, code, type FROM t_order
ORDER BY code
LIMIT 1000000, 10;
// todo 覆盖索引更多的了解
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)