命中索引

1 Create TABLE ‘t'(
2 'id' int(11) not null,
3 'a' int(11) default null,
4 'b' int(11) default null,
5 primary key ('id'),
6 key 'a' ('a'),
7 key 'b' ('b')
8 )ENGINE=InnoDB;
select * from t where a between 10000 and 20000;  优化器选择了索引a

rows字段表示预计扫描行数。

select * from t force index(a) where a between 10000 and 20000;

优化器的逻辑

在数据库里面,扫描行数是影响执行代价的因素之一。扫描的行数越少,意味着访问磁盘数据的次数越少,消耗的 CPU 资源越少。

扫描行数并不是唯一的判断标准,优化器还会结合是否使用临时表、是否排序等因素进行综合判断。普通索引还会考虑回表的代价。

扫描行数是怎么判断的?根据统计信息来估算记录数,这个统计信息就是索引的“区分度”。一个索引上不同的值越多,这个索引的区分度就越好。而一个索引上不同的值得个数,称为“基数”。

MySQL是怎样得到索引的基数的呢?采样统计

采样统计的时候,InnoDB 默认会选择 N 个数据页,统计这些页面上的不同值,得到一个平均值,然后乘以这个索引的页面数,就得到了这个索引的基数。

对于由于索引统计信息不准确导致的问题,可以用 analyze table 来解决。

analyze table t

索引选择异常和处理

1.采用force index强行选择一个索引

2.修改SQL语句

3.新建更合适的索引,或删掉误用的索引

 

posted @ 2020-03-31 09:41  LinBupt  阅读(299)  评论(0编辑  收藏  举报