在基础架构里提到在执行查询时优化器负责选择使用哪个索引。
实验1
建表:
|
|
插入数据:
|
|
用explain`来观察MySQL会选择哪个索引:
|
|
结果表明MySQL会选择索引a,并且预计扫描10001行,为什么是10001行而不是10000行?这是因为在扫描的时候要扫描到第一个不满足条件的数据为止,因此会多扫一行。
选错索引的逻辑
优化器选择索引考虑的因素:
- cardinality(基数),基数代表区分度,基数越大区分度则越大,不同值越多则区分度越大,区分度大的索引被选择的概率大
|
|
基数的值并非精确值而是一个估算值,InnoDB选取N个数据页统计不同值,计算基数平均值。当更新的行超过1/M时,重新计算基数。可以用innodb_stats_persistent
来控制这个统计信息存在哪里。
- 预估执行该语句本身会扫描多少行,同时会预估回表的代价
纠正办法
重新统计索引信息:
|
|
强制告诉使用哪个索引,force index
:
|
|
其他tricky的方法,这里不做介绍了。
评论