![d5f3f83dbcfb4a79cc562f72a9f61c49.png](https://i-blog.csdnimg.cn/blog_migrate/655283a22c7bb24069531ca9ece9de90.png)
《sql优化核心思想》读书笔记
《sql优化核心思想》读后分享
小作者:王城超
读完《sql优化核心思想》,有几点总结,先说几个概念名词。1.基数:某字段不同的结果数量,如主播表的user_id共有n种不同值,n是此字段基数。2.选择性:基数÷总条数,是0~1之间的值,如主键字段的选择性一定为1,如共100条记录的主播表gender字段的选择性为2/100=0.02。
再介绍一个最省力但不准确的索引创建标准:只为选择性大于0.2的字段建立索引。为什么说这个不准确?因为选择性其实和数据分布的很多点都无关,只和平均一个基数的结果条数有关,例如:一个主播日收益表,只录入了2个主播的10天的数据,那么总条数是20,而主播id字段的选择性是2/20=0.1,另一张主播日收益表,录入了1000个主播10天的数据,那么主播id字段选择性为1000/10000=0.1,选择性未变,但常识是第2张表毋庸置疑,要在主播id字段上建立索引(因为总条数上万,且当主播id字段等值查询,若走索引,会从全表扫描的10000的规模降到10的规模)。
所以较准确的说法是:当返回数据是全表的5%以下,应该走索引。5%以上,走全表扫描。
如果走索引就要考虑回表,当对一个列创建索引之后,索引会包含该列的键值以及键值对应行所在的rowid。通过索引中记录的rowid访问表中的数据就叫回表。回表一般是单块读,回表次数太多会严重影响SQL性能,如果回表次数太多,就不应该走索引扫描了,应该直接走全表扫描,或者用后面会说的组合索引。
单块和多块读,多块读有:不需要回表的走索引,全表扫描。单块读有:需要回表的走索引等等……几乎除了上面2个多块读,其他访问路径都是单块读。绝大多数的平台,一次I/O最多只能读取或者写入1MB数据,例如:块大小默认是8k,那么一次I/O最多只能写入128个块到磁盘。在判断哪个访问路径性能好的时候,通常是估算每个访问路径的I/O次数,谁的I/O次数少,谁的性能就好。
那么如何判断mysql执行计划将走索引or全表?可以使用explain命令:走索引的常见几种访问路径(oracle叫访问路径,mysql叫access_type)有(以下都为mysql叫法): 1.ref(非unique索引的等值查找) 2.range(unique索引和非unique索引的范围查找) 。
Explain命令还可以判断这些访问路径以及分是否需要回表,若explain结果的Extra值为Using index,则不需要回表。另一判断依据是看,索引的字段集是否全都涵盖了要select的字段,若全涵盖到了,则不需要回表。
![9f447f1b1d32828494eba806359028e3.png](https://i-blog.csdnimg.cn/blog_migrate/f6d16b85870f041e3f6f924006ff4c23.png)
![d0ea406a27e36fee67593315de5b83f5.png](https://i-blog.csdnimg.cn/blog_migrate/6210896c15e3929c3293bfd4b100c8b5.jpeg)