优化成本
读取一个页面花费的成本默认为1.0。
读取以及检测一条记录是否符合搜索条件的成本默认是0.2。
找出成本最低的方法的过程:
- 根据搜索条件,找出所有可能使用的索引。
- 计算全表扫描的代价。
- 计算使用不同索引执行查询的代价。
- 对比各种执行方案的代价,找出成本最低的那个方案。
全表扫描的代价:
- 聚簇索引占用的页面数
- 该表中的记录数
二级索引+回表的代价:
- 扫描区间数量
- 需要回表的记录数
index dive:通过直接访问索引对于的B+树来计算机某个扫描区间内对应的索引记录条数。
IN语句中对应的单点区间数量大于或者等于系统变量eq_range_index_dive_limit的值的时候,就不使用index dive来计算各个单点区间对应的索引记录条数。而是使用索引统计数据:
- 使用SHOW TABLE STATUS语句显示出Rows值:表示一个表中有多少条记录
- SHOW INDEX语句显示的Cardinality属性
连接查询的成本
连接查询总成本=单词访问驱动表成本+驱动表扇出值*单次访问被驱动表的成本
驱动表的扇出:查询驱动表后得到的记录条数。
- 如果使用全表扫描的方式执行单表查询,那么计算驱动表扇出值时需要猜测满足全部搜索条件的记录到底有多少条。
- 如果使用索引来执行单表查询,那么计算驱动表扇出值时需要猜测除了满足形成索引扫描区间的搜索条件外,还满足其他搜索条件的记录有多少条。
这个猜测的过程就是Condition Filtering(条件过滤)。
外连接的驱动表固定,只需要分别为驱动表和被驱动表选择成本最低的访问方法。
内连接考虑两方面:
- 不同表作为驱动表的时候,查询成本不同,考虑最优表连接顺序
- 分别为驱动表和被驱动表选择成本最低的访问方法
优化重点:
- 减少驱动表扇出
- 访问被驱动表的成本要降低
多表连接的成本分析
- 维护一个最小连接查询成本
- 连接表个数小于optimizer_search_depth值,就继续穷举分析每一种连接顺序的成本,否则只对数量与optimizer_search_depth相同的表进行穷举分析。
- 凡是不满足规则的连接查询不分析