我们都知道语句执行时会经过 优化器 在交给引擎
-
但是有时候优化器并不能正确选择索引
-
优化器会找到一个最优的执行方案 并用最小的代价去访问,在数据库里面,扫描行数是影响执行代价的因素之一。扫描的行数越少,意味着访问磁盘数据的次数越少,消耗的CPU资源越少。
-
对于一个具体的语句来说 优化器还需要判断执行语句本身需要多少行
MySQL 是如何判断行数的
-
mysql 在执行中不能清楚的知道这个条件的记录有多少条 只能根据信息来估计记录数
-
mysql 根据索引的“区分度“ 也就是一个索引上不同值得个数,我们称为 “基数”
mysql 是如何获取基数的?
- mysql 使用采样统计行数
- 统计时innoDb 会选择N个数据页,统计页面的不同值,得到一个平均再去乘以索引总页数得到基数
- 当变更超过数据1/M 时 会触发一次索引统计
-
设置索引统计 innodb_stats_persistent
- on N=20 M=10
- OFF N=8 M=16
如何矫正索引
- 我们可以使用force index 强制指定索引
- analyze table t 修正统计索引信息
- 修改语句测试