MySQL性能优化---EXPLAIN
参见:https://blog.csdn.net/jiadajing267/article/details/81269067
参见:https://www.cnblogs.com/clphp/p/5403215.html
explain关键字用于分析sql语句的执行情况,可以通过他进行sql语句的性能分析。
对explain查询出来的结果含义进行分析:
id值的含义:
id为语句的查询序号,也就是查询的执行顺序,如果id值相同表示语句是自上而下的执行的,如果值不相同,id值越大,优先级越高,越先执行。
select_type的含义:
它是标记sql语句的查询类型。查询类型,主要用于区别普通查询,联合查询,子查询等的复杂查询。主要有以下六种情况:
- 1、simple ——简单的select查询,查询中不包含子查询或者UNION
- 2、primary ——查询中若包含任何复杂的子部分,最外层查询被标记
- 3、subquery——在select或where列表中包含了子查询
- 4、derived——在from列表中包含的子查询被标记为derived(衍生),MySQL会递归执行这些子查询,把结果放到临时表中
- 5、union——如果第二个select出现在UNION之后,则被标记为UNION,如果union包含在from子句的子查询中,外层select被标记为derived
- 6、union result:union的结果,也就是联合查询的结果
table的含义:
它的含义是表示在查询语句中使用了那些表。
type的含义:
type显示的是访问类型,是较为重要的一个指标,显示联结类型,显示查询使用了何种类型,按照从最佳到最坏类型排序:
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL ,一般来说,得保证查询至少达到range级别,最好能达到ref。
1、system:表中仅有一行(=系统表)这是const联结类型的一个特例。
2、const:表示通过索引一次就找到,const用于比较primary key或者unique索引。因为只匹配一行数据,所以如果将主键置于where列表中,mysql能将该查询转换为一个常量
3、eq_ref:唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配。常见于唯一索引或者主键扫描
4、ref:非唯一性索引扫描,返回匹配某个单独值的所有行,本质上也是一种索引访问,它返回所有匹配某个单独值的行,可能会找多个符合条件的行,属于查找和扫描的混合体
5、range:只检索给定范围的行,使用一个索引来选择行。key列显示使用了哪个索引,一般就是where语句中出现了between,in等范围的查询。这种范围扫描索引扫描比全表扫描要好,因为它开始于索引的某一个点,而结束另一个点,不用全表扫描。
6、index:index 与all区别为:index类型只遍历索引树。通常比all快,因为索引文件比数据文件小很多。
7、all:遍历全表以找到匹配的行
possible_keys的含义:
指出MySQL能使用哪个索引在该表中找到行,一般为索引和主键。也就是表示能够通过他找到所查数据记录。
key的含义:
显示MySQL实际决定使用的键(索引)。如果没有选择索引,键是NULL,也就是说在你的查询select中实际是用到了主键还是用到了索引进行查询。如果都没有用到则为null。
key_len的含义:
显示MySQL决定使用的键长度。如果键是NULL,则长度为NULL。使用的索引的长度。在不损失精确性的情况下,长度越短越好。
ref的含义:
显示使用哪个列或常数与key一起从表中选择行。
rows的含义:
显示select语句检索的行数,也就是说这个sql语句检索了这么多行才找到符合条件的记录。
Extra的含义:
包含MySQL解决查询的详细信息,也是关键参考项之一。
Distinct
一旦MYSQL找到了与行相联合匹配的行,就不再搜索了Not exists
MYSQL 优化了LEFT JOIN,一旦它找到了匹配LEFT JOIN标准的行,就不再搜索了Range checked for each
Record(index map:#)
没有找到理想的索引,因此对于从前面表中来的每一 个行组合,MYSQL检查使用哪个索引,并用它来从表中返回行。这是使用索引的最慢的连接之一Using filesort
看 到这个的时候,查询就需要优化了。MYSQL需要进行额外的步骤来发现如何对返回的行排序。它根据连接类型以及存储排序键值和匹配条件的全部行的行指针来 排序全部行Using index
列数据是从仅仅使用了索引中的信息而没有读取实际的行动的表返回的,这发生在对表 的全部的请求列都是同一个索引的部分的时候Using temporary
看到这个的时候,查询需要优化了。这 里,MYSQL需要创建一个临时表来存储结果,这通常发生在对不同的列集进行ORDER BY上,而不是GROUP BY上Using where
使用了WHERE从句来限制哪些行将与下一张表匹配或者是返回给用户。如果不想返回表中的全部行,并且连接类型ALL或index, 这就会发生,或者是查询有问题
当type 显示为 “index” 时,并且Extra显示为“Using Index”, 表明使用了覆盖索引。
sql的解析
mysql的书写顺序
select distinct
<select_list>
from
<left_table><join_type>
join <right_table> on <join_condition>
where
<where_condition>
group by
<group_by_list>
having
<having_condition>
order by
<order_by_condition>
limit
总的来说mysql的书写顺序就是select ...from ...where ...group by....having...order by...limit。
mysql的执行顺序
1、from <left_table><join_type>
2、on <join_condition>
3、<join_type> join <right_table>
4、where <where_condition>
5、group by <group_by_list>
6、having <having_condition>
7、select
8、distinct <select_list>
9、order by <order_by_condition>
10、limit <limit_number>
mysql的执行顺序是首先从from开始执行,表示从那张表去查询,接着是on,where条件子句,其次是分组,按照什么条件来进行分组,然后才是select查询出结果,然后对结果进行去重,排序,分页等操作。