查询优化器-学习

161 阅读2分钟

1、简介

SQL查询之前,会先经过「查询优化器」,优化器会基于最低成本选择用什么方式查询,是全表还是某个索引;

成本最低的方案,就是「执行计划」,之后会调用存储引擎接口查询数据;

2、成本分类

I/O成本

InnoDB存储引擎将数据与索引存储在磁盘,我们需要查询表数据时,会从磁盘把数据加载到内存中。从磁盘到内存加载过程所消耗的时间称为I/O成本。

CPU成本

读取以及检测记录是否符合条件、对结果排序等。这些操作的耗时称为CPU成本。

InnoDB规定读取一页成本为1,读取一条以及检测是否符合规则成本为0.2;

3、优化步骤

3.1、根据查询条件,获取可能用到的查询;

主键索引、某些普通索引;

3.2、计算全表扫描的成本

  1. 全表扫描就是将「聚簇索引」全部数据与查询条件做对比,符合条件的加入结果集;
  1. 全表扫描成本:I/O成本+CPU成本。所以需要知道,全表有多少页,有多少记录,才可以算出成本;
  1. 通过 show table status like 表, 获取到rows、data_length字段;
rows:是有多少条记录;data_length = 页数量 * 页大小(默认16KB);
页数量 = data_length / 16 / 1024;
​
总成本 = I/O成本 + CPU成本 = 页数量 * 1 + rows * 0.2;  

3.3、计算主键索引扫描成本

计算主键索引成本:主要是知道where条件在主键索引B+树中存在多少条记录;

  1. I/O成本为1。当从索引中查询数据,不管是 =、in、>、<查询,查询优化器都认为I/O成本跟读取一页的成本相同;
  2. 计算CPU成本。 =、in、>、<都是有范围的,CPU成本就是范围内的记录数 * 0.2;

3.3、计算二级索引扫描成本

  1. 二级索引需要回表操作,需要把回表的成本也加上。
回表成本:select  * fromwhere id in ( 主键1,主键2,主键3); 
​
总成本 = 二级索引查询成本 + 回表成本;
  1. 如果in中的个数过多(超过200个),会通过show index form 表,查询到索引大概的数据。
  2. NULL的问题。InnoDB认为每个null都是相等的,如果某个索引中null值特别多的话,会让优化器认为平均一个值重复次数特别多,则不使用索引进行访问。

最好不要允许索引允许为null;

3.4、选出最低成本的来查询