作者 | 吴海存
责编 | 徐威龙
封图| CSDN下载于视觉中国
导读:
本文主要针对limit分页时,是优先基于主键索引还是辅助索引等层面展开分析,对limit及offset的用法以及是否该用索引不会过多赘述。
我们知道,在Mysql中可以通过limit实现快速分页,但是如果表中数据量较大,则分页后期可能会十分缓慢,这是由limit的工作机制决定的,比如limit 500000,5的意思扫描满足条件的500005行,扔掉前面的500000行,返回最后的5行,所以我们在分页的时候,需要通过相应的索引来快速定位到第500000行,然后将后面的5行数据输出即可。
那我们在选则索引的时候,是使用主键索引还是使用辅助索引呢?若使用辅助索引,那对该辅助索引有没有什么限制呢?比如该索引所基于的列是不是应该有not null约束呢?因为我们知道,在分页的时候,要求数据是连续的,而索引里面是不记录null值的,所以若索引没有not null约束,则有可能不满足分页条件。
对于以上几个问题,我们通过如下的示例来一一验证说明,如有疏漏之处,望指正。
实验环境
MySQL版本:8.0.18
OS版本:CentOS 8.0
【实验步骤】
1.确认测试表emp中的数据量(若数据量太少,则对比效果不明显)
2.确认表上索引和not null约束信息
说明: id 上索引为主键索引
empno上的索引ind2为唯一性非空索引
ename 上的索引ind3为非空的普通索引
salary 上的索引为可以为空的普通索引
3.收集最新的统计信息
为了测试的公平性,我们执行一次全表查询,模拟将表emp的page尽量多地缓存到buffer pool,否则可能会出现后执行的sql直接逻辑读取了先执行的sql通过物理IO读到buffer pool的page,会使得对比结果缺乏不可靠性。
为了体现测试效果,我们选择扫描700W+5行,然后舍弃前面的700W行,返回后面满足条件的5行。
4.1在分页的时候通过ID列选择使用主键索引
select * from emp where id >= (select id from emp order by id limit 7000000,1) limit 5;
相应的执行计划使用了主键索引PRIMARY:
可以看到,使用ID主键索引的时候,用时为2.87秒。
4.2使用非空唯一性索引
select * from emp where empno >= (select empno from emp order by empno limit 7000000,1) limit 5;
相应执行计划使用了非空唯一性索引ind2:
当使用非主键以外的非空唯一性索引时,用时0.85秒。
4.3使用非空非唯一的索引
select * from emp where ename >= (select ename from emp order by ename limit 7000000,1) limit 5;
相应执行计划使用了非空非唯一性索引ind3:当使用非空非唯一性索引时,用时1.95秒。
4.4使用可为null的普通索引
先随机设置20行salary为null
查5条数据验证一下:
更新统计信息:
使用可为null的普通索引进行分页:
执行计划使用了可为null非唯一性索引:
当使用可为null非唯一性索引时,用时1.18秒,使用的时间比非唯一性索引ind3时间较短的原因,是因为ind4的key_len是5,而ind3的key_len是82,ind3需要读取更多的page。
4.5验证使用可为null的普通索引是否会丢失数据
这里有一个问题,就是ind4里会有null值,使用该列进行分页的话,是不是由可能会丢失数据呢?使用如下步骤进行验证:
增到表中salary为null的行数到100
对salary进行排序,然后选择扫描7999910行,然后舍弃前面的7999890行,返回后面满足条件的20行,看数据库返回得行数:
可以发现,当使用可为null的非唯一性索引时,会将null值当作最小值参加排序,不会丢失数据。
通过实验验证,我们可以得出如下结论:
1.当使用非主键的唯一性非空索引时,用作分页效率最高。
2.若使用primary key, 因为innodb时IOT表,所有全索引访问等同于全表扫描,效率低。
3.若同为普通索引,则和该索引的key长度,选择率等有关系,若该索引的选择率较高,则效率会高于primary key,原因同第二条。
4.使用可为null的非唯一性索引时,会将null值当作最小值参加排序,不会丢失数据。
对于本文,你有什么想法?欢迎在评论区和我讨论。
作者介绍:
吴海存,10g/11g/12c OCM, Oracle Exadata/Golden Gate 专家, 曾于Amazon和Oracle公司担任全球业务资深DBA,目前供职于中国农业银行,担任资深数据库专家。
同时,欢迎所有开发者扫描下方二维码填写《开发者与AI大调研》,只需2分钟,便可收获价值299元的「AI开发者万人大会」在线直播门票!
推荐阅读:如何成功构建大规模 Web 搜索引擎架构?
“出道” 5 年采用率达 78%,Kubernetes 的成功秘诀是什么?
一群阿里人如何用 10 年自研洛神云网络平台?技术架构演进全揭秘!拿下 Gartner 容器产品第一,阿里云打赢云原生关键一战!
大话卷积神经网络CNN,小白也能看懂的深度学习算法教程,全程干货建议收藏!
朱广权李佳琦直播掉线,1.2 亿人在线等
“抗疫”新战术:世卫组织联合IBM、甲骨文、微软构建了一个开放数据的区块链项目!
真香,朕在看了!