2019-08-17第十讲:Mysql会选错索引[mysql实战

2019-08-17  本文已影响0人  Mr钧

1. 复现例子. 

2.例子对应的是不断删除历史数据, 然后insert新数据的场景. 

1.优化器的逻辑: 

    1.优化器的目的: 找到一个最优的执行方案

    2.最优判断方式: 扫描行数, 是否使用临时表, 是否排序. 

   3.扫描行数是如何判断的 ? 

        1.根据统计信息估算

            统计信息==> 索引的区分度

            索引上不同值的个数 ==> 基数

            ==> 基数越大,区分度越高

            ==> show index  可以看到基数. cardinality 

                    注意: 实际上基数都应该是10万, 

1  show index

    4.mysql是怎么得到索引基数的? 

        1. 采样统计:  因为全表扫描代价大. 

            基数 ==> 默认选择N个数据页, 统计页上的不同值, 得到一个平均值, 乘以这个索引的页面数. 

            因为数据表会持续更新 ==> 当变更的数据行数超过1/ M的时候, 触发一次索引统计. 

            两种存储索引统计的方式 : innodb_stats_persistent

                ==> on ==> 持久化 N=20, M10

                ==> off ==> 内存 N=8 M=16

    5.索引统计只是入参, Mysql需判断SQL语句本身要扫描多少行.

5,意外的 expalin 结果

疑问2: 为什么放着row 30000+的不用, 用100000+的执行计划呢? 

    答: 因为回表的时间优化器也计算在内

    ==> 推断1: 主键索引比普通索引优先级高. 

疑问3 :  为什么会得到错误的扫描行数 ? 

    6.解决统计信息错误 => analyze table  t; 

6 analyze table t 后, explain

2.索引选择异常和处理

1.解决方案1 : force index  ==> 硬编码;

2. 修改SQL 引导Mysql

3.新建一个索引, 或者 删除误用索引. 

==> 推论3:  对于优化器来说:  索引统计, 排序,使用临时表是有同等权重的. (看源码把)

    

上一篇下一篇

猜你喜欢

热点阅读