1.我们怎么知道sql执行效果怎样哪?我们需要查询sql的执行计划。mysql优化器是怎样执行我们的请求的。
explain select * from user where username = 'lai' and password = 'lai';
2.首先通过mysql执行计划,我们可以知道sql如何使用索引。虽然我们在列上加了索引,但是sql执行过程中未必走索引。所以我们需要通过执行计划确认是否正确使用到了索引。
此外我们还可以知道多表链接查询时,表链接顺序。mysql执行计划会根据索引动态调整表关联顺序。同时我们还可以知道当前sql需要扫描的数据行数。有时返回的结果集中仅仅只有几行数据,但是却要扫描几百或上前万行数据。
也就是说没有正确使用到索引。
3.mysql执行计划可能输出多行,每一行对一个数据库对象的操作。按照执行计划的输出顺序看sql告诉我们那些内容。
3.1 ID列中的数据有两种情况:
(1)一组数字:1,2,3,4;表示sql语句对于数据库的操作顺序。
(2)null这样行数据由另外两个语句union执行后的结果集。
那么既然id值表示sql执行顺序,ID值相同的情况说明执行顺序由上至下。
id值不相同,那么表示ID值越高优先级越高,优先被执行。id值可以看作sql中select操作的序号。第一个select语句序号1,第二个select语句序号2。这样由上至下执行。
3.2SELECT_TYPE列
simple不包含子查询或是union操作的查询
primary查询中如果包含任何子查询,那么最外层的查询则被标记为primary。
subqueryselect 列表中的子查询
dependentsubquery 依赖外部结果的子查询
unionunion操作的第二个或是之后的查询(select)的值为union
dependentunion 当union作为子查询时,第二个或是第二个后的查询的select_type值
unionresult union产生的结果集。
derived 出现在from子字句的子查询
3.3TABLE列
输出数据行所在的表名称。(表名或别名)
3.4partutuibs列
对于分区表,显示查询分区的ID。查询到结果所查询到的所有分区id。
若没有分区,显示null.
3.5type列
mysql默认所有的查询都是关联查询。
性能 |
值 |
说明 |
高 |
System |
这是const链接类型的一个特例,当查询的表只有一行数据时使用 |
|
Constant |
表中由且只有一个匹配的行。如对主键或者唯一索引的查询。 |
|
Eq_ref |
唯一索引或主键索引查找。每一个索引键,表中只有一条记录匹配 |
|
Ref |
非唯一索引查找,返回匹配某个单独值的所有行 |
|
Ref-or-null |
类似于ref类型的索引。但是附加了对null值列的查询。 |
|
Index-marge |
使用了索引合并优化方法 |
|
Range |
索引范围扫描,常见与bewteen,<,>这样的查询 |
|
Index |
Full index scan全索引扫描,同ALL的区别是遍历的是索引数 |
|
ALL |
FULL table scan全表扫描 |
3.7扩展列extra
值 |
含义 |
Distinct |
优化distinct操作,在找到第一个匹配的元素后即停止找相同值的动作 |
Not exists |
使用Not exists来优化。例如优化not in |
Using filesort |
使用额外操作进行排序,通常会出现在Orderby groupby中 |
Using index |
使用了覆盖索引进行查询 |
Using temporary |
Mysql需要使用临时表来查询,常见于排序,子查询,分组查询 |
Using where |
需要在mysql服务器层使用where条件来过滤 |
Select tables optimized away |
直接通过索引来获取数据。不用访问表。 |
3.8 POSSIBLE_KEYS列
指出Mysql能使用哪些索引来优化查询,但是可能没有使用。
3.9 key列
查询优化器优化查询实际所使用的索引。没有则显示null.
3.10 key_len列
Mysql在索引里所使用的字节数。在联合索引中有3列,3列的字段长度可能是100个字节,key_len可能小于100个字节,这说明联合索引没有用到所有的列,利用到其中1~2列。
Key_len的长度是用字段定义来决定的并非数据的实际长度。
3.11 ref列
表示哪些列或常量被用于索引查找列上的值。换句话说就是查询所利用的索引值来源于哪些列或者常量。
3.12 rows列
Mysql通过索引统计信息,估算出所需读取的行数。在关联查询的时候rows列所显示的行数是每一次嵌套查询时所需要查询的行数。
Rows值的大小是统计抽样的结果,并非十分准确。
3.13 filtered
表示返回结果的行数占需要读取行数的百分比。参考值,并非十分准确。
4.执行计划的限制
无法展示存储过程,触发器,UDF对查询的影响。
建立联合索引的第一步就是确定区分度:
Selectcount(distinct name)/count(1) from user;
Selectcount(distinct phone)/count(1) from user;
区分度越大表示相同数据越少。
Createindex idx_phone_name on user(phone, name)