SQL优化
覆盖索引
覆盖索引:查询语句从执行到返回结果均使用同一个索引,可以有效减少回表。若数据的查询不只使用了一个索引,则不是覆盖索引,可以通过优化SQL语句或优化联合索引,来使用覆盖索引
提高索引覆盖率
MySQL在选取索引是,会参考索引的基数(Cardinality), 基数是MySQL估算的,反映这个字段有多少种取值,选取几个页算出取值的平均值,再乘以页数,即为基数。
强制使用索引
使用force index可以强制使用索引
优化索引
analyze table可以重新统计索引信息,重新统计索引信息时,会重新计算索引的基数
count使用
count(非索引字段)时,server层需要判断每个数据是否为null,而且查询本身无法使用覆盖索引,理论上最慢;count(索引字段)能提速,可以使用覆盖索引但依然要取出数据判空,count(1)不需要取出数据,但需要判断1是否为null。count()做了优化,一般用来返回数据表行数,MyISAM的count()直接返回数据库中记录的数据表行数,由于InnoDB支持事务,数据库中不记录数据表行数,MySQL专门优化了count(*)直接返回索引数中数据的个数。
order by优化
order by原理
根据where等条件查询,将查询结果放入sort_buffer,对中间结果集按照order字段排序,回表生产完整结果集
条件查询
给查询字段加颙,可以改善条件查询速度
中间结果集
中间表比较小,直接放在内存中,中间表大于sort_buffer_size时,放在硬盘中,若需要优化内存占用,减小sort_buffer_size,若需要优化排序查询时间,增大sort_buffer_size
回表生产完整的结果集
当行小于max_length_for_sort_data时,生产全字段中间表,大于阀值时只生成排序字段+主键中间表,需要回表,调大阀值并不一定改善效率,因为太大的结果集排序效率低
最高效-索引覆盖
索引覆盖可以跳过生成中间结果集,直接输出查询结果,order字段需要有索引(或在联合索引左侧),其他相关字段(条件,输出)均在上述的索引中
MySQL排序一般需要生成中间结果集,排序,回表的过程,索引覆盖是最高效的处理排序的方式
|