一.优化器的逻辑
选择索引是优化器的工作
优化器选择索引的目的:
- 找一个最优的执行方案,用最小的代价执行语句
- 执行行数是影响执行代价的因素之一。
- 扫描的行数越少,意味着访问磁盘数据的次数越少 ,消耗CPU资源越少。
优化器还会结合是否使用临时表,是否排序等因素。
二.扫描行数怎么判断
show index方法 查看索引基数
MySQL得到索引的基数
采样统计:
- 整张表取出来一行行统计,虽然可以得到精确的结果但是代价很高,只能选择“采样统计”
- InnoDB默认选择N个数据页,统计这些页面上的不同值,得到一个平均值,然后乘以这个索引的页面数,得到索引基数。
- 当变更的数据杭超过1/M的时候会自动触发一次索引统计。
innodb_stats_persistent
统计磁盘还是内存
- 设置on时候,统计持久化存储
- 设置off时候,统计内存中信息
analyze table t 可以用来统计索引信息
索引选择异常和处理
大多数时候优化器都能找到正确的索引,但是偶尔你还是会碰到上面情况:
缺点:
- 程序员不喜欢使用force index,索引改完名字,这个语句就需要改。
优点:
- 使用force index最主要的问题还是变更的及时性。一般等待线上出现问题的时候,才会修改SQL语句,加上force index。但是修改之后还要测试和发布。对于生产系统来说,这个过程不够敏捷。
2.修改语句,引导 MySQL 使用我们期望的索引
3.可以新建一个更合适的索引,来提供给优化器做选择,或删掉误用的索引