《MYSQL实战45讲 》 优化器如何选择索引?

复制代码
SHOW VARIABLES LIKE 'long_query_time';
复制代码
set long_query_time=0

优化器如何选择索引?

1.扫描的行数

估计出各个索引大致的要扫描的行数,行数越少,效率越高。

索引的基数也叫区分度,就是这个索引所在的字段上不同的值又多少个。优化器通过各个索引的区分度来估计这条查询语句满足条件的记录又多少条。mysql是通过采样统计的方法估算出各个索引的基数的,也就是抽查20个数据页,然后统计这些页面上该索引所在字段的不同值的个数,计算出平均值,然后乘以这个索引的页面数,就得到索引的基数。但是这个基数是会更新的,当变更的数据行数超过十分之1时就会重新做一次统计。

2.对于具体的一个查询语句,优化器会预估这个语句要扫描多少行

就是explain之后的rows字段。

但是优化器不单单会比较多个索引的预估扫描行数,还会考虑到二次索引查询数据还要回表的问题,而主键索引不需要回表,尽管预估扫描可能更多,但是可能仍然选择主键索引

analyze table t命令,可以用来重新统计索引信息

对于这个查询语句

复制代码
SELECT * from t WHERE (a BETWEEN 1 and 1000) and (b BETWEEN 50000 and 100000) order by b LIMIT 1

优化器可以选择a索引,也可以使用b索引

1.假如选择a索引:

首先扫描索引a的前1000个值,然后查到每个记录对应的id,再回主键索引表去查出每一行,根据字段b来过滤。这样只需要扫描1000行

2.假如选择b索引,那就要扫描索引b的最后50001个值,需要扫描50001行

看起来选择a索引的话性能会更好,但是实际上优化器使用了b索引,错选的原因是优化器看到了后面的order by b 如果用b索引的话就避免排序了,因为索引的b+树节点本身就是有序的,如果先选择b索引来查,查出来的数据就是有序的,避免排序了。

相关推荐
啵啵啵鱼13 分钟前
对数据的增删改查
数据库·mysql·ai·idea·ai编程·navicat·obsidian
靠沿18 分钟前
MySQL数据库基础——索引的使用&alter、explain关键字
java·数据库·mysql
赵渝强老师20 分钟前
【赵渝强老师】Oracle的行地址:ROWID
数据库·oracle
重生之高冷汉堡包23 分钟前
什么是数据中心代理?原理拆解、类型区别、应用场景与选型指南
服务器·网络·数据库·安全·ip
Mortalbreeze24 分钟前
MySQL 基础篇(八):复合查询之多表查询、内外连接、子查询
数据库·mysql
Xxtaoaooo27 分钟前
NocoDB在线表格数据库:fnOS部署、MySQL可视化与远程协作实操
数据库·mysql·docker·cpolar·nocodb
张继雁32 分钟前
30~50MPa数控高压清洗:前端分级过滤逻辑,抑制硬质磨粒对喷嘴冲蚀
大数据·数据库·人工智能·机器学习·创业创新
言乐635 分钟前
PythonLOLM自动生成复盘报告模型
开发语言·前端·数据库·人工智能·python
倔强的石头_38 分钟前
从 KStudio 到 KSQL Developer:国产数据库的 SQL 编辑器,已经卷到这个程度了
数据库
JavaEdge.1 小时前
设定索引方法和检索设置
数据库