做网站运营需要培训吗,做虾苗网站有哪些流程,旧房翻新装修多少钱一平方,撤销网站备案申请书1 EXPLAIN概念EXPLAIN会向我们提供一些MySQL是执行sql的信息#xff1a;EXPLAIN可以解释说明 SELECT, DELETE, INSERT, REPLACE, and UPDATE 等语句.当EXPLAIN与可解释的语句一起使用时#xff0c;mysql会显示一些来自于优化器的关于sql执行计划的信息。即mysql解释它是如何处…1 EXPLAIN概念EXPLAIN会向我们提供一些MySQL是执行sql的信息EXPLAIN可以解释说明 SELECT, DELETE, INSERT, REPLACE, and UPDATE 等语句.当EXPLAIN与可解释的语句一起使用时mysql会显示一些来自于优化器的关于sql执行计划的信息。即mysql解释它是如何处理这些语句的和表之间是如何连接的。想获取更多关于EXPLAIN如何获取执行计划信息的。当EXPLAIN后面是一个会话的connection_id 而不是一个可执行的语句时它会展示会话的信息。对于SELECT语句EXPLAIN会产生额外的执行计划信息这些信息可以用SHOW WARNINGS显示出来。EXPLAIN对于检查设计分区表的查询时非常有用。FORMAT选项可以用于选择输出格式如果没有配置FORMAT选项默认已表格形式输出。JSON 选项让信息已json格式展示。2 EXPLAIN 输出列信息EXPLAIN输出的字段信息第一列:列名, 第二列:FORMAT JSON时输出中显示的等效属性名称 ,第三列字段含义ColumnJSON NameMeaningidselect_idselect标识号select_typeNoneselect类型tabletable_name这一行数据是关于哪张表的partitionspartitions匹配的分区对于未分区表该值为空typeaccess_type使用的连接类别,有无使用索引possible_keyspossible_keysMySQL能使用哪个索引在该表中找到行keykeyMySQL实际决定使用的键(索引)key_lenkey_lengthMySQL决定使用的键长度。如果键是NULL长度为NULLrefref与索引关联的列rowsrowsmysql认为执行sql时必须被校验的行数filteredfiltered表示此查询条件所过滤的数据的百分比ExtraNone附加信息2.1 idSELECT标识符。SELECT在查询中的序列号可以为空。2.2 select_typeSELECT类型所有类型在下表中展示JSON格式的EXPLAIN将SELECT类型公开为query_block的属性除非它是SIMPLE或PRIMARY。 JSON名称(不适用为None)也显示在表中。select_type ValueJSON NameMeaningSIMPLENone简单SELECT(不使用UNION或子查询等)PRIMARYNone嵌套查询时最外层的查询UNIONNoneUNION中的第二个或后面的SELECT语句DEPENDENT UNIONdependent (true)UNION中的第二个或以后的SELECT语句取决于外部查询UNION RESULTunion_resultUNION的结果SUBQUERYNone子查询中的第一个选择DEPENDENT SUBQUERYdependent (true)子查询中的第一个选择取决于外部查询DERIVEDNone派生表(子查询中产生的临时表)MATERIALIZEDmaterialized_from_subquery物化子查询UNCACHEABLE SUBQUERYcacheable (false)无法缓存结果的子查询必须对外部查询的每一行进行重新计算UNCACHEABLE UNIONcacheable (false)UNION中属于不可缓存子查询的第二个或以后的选择(请参 UNCACHEABLE SUBQUERY)表信息(后面演示用)mysql show create table t_a;------| t_a | CREATE TABLE t_a (id bigint(20) NOT NULL DEFAULT 0,age int(20) DEFAULT NULL,code int(20) NOT NULL,PRIMARY KEY (id),UNIQUE KEY uk_code (code),KEY age_key (age)) ENGINEInnoDB DEFAULT CHARSETgbk |------------------------------------------------1 row in set (0.03 sec)SIMPLE简单SELECT(不使用UNION或子查询等)mysql explain select * from t_a where id 1;----------------------------------------------------------------------------------------------------------| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |----------------------------------------------------------------------------------------------------------| 1 | SIMPLE | t_a | NULL | const | PRIMARY | PRIMARY | 8 | const | 1 | 100.00 | NULL |----------------------------------------------------------------------------------------------------------1 row in set, 1 warning (0.03 sec)PRIMARY嵌套查询时最外层的查询mysql explain select * from t_a where num (select num from t_a where id 3);-----------------------------------------------------------------------------------------------------------------------------| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |-----------------------------------------------------------------------------------------------------------------------------| 1 | PRIMARY | t_a | NULL | range | num_key | num_key | 5 | NULL | 6 | 100.00 | Using where; Using index || 2 | SUBQUERY | t_a | NULL | const | PRIMARY | PRIMARY | 8 | const | 1 | 100.00 | NULL |-----------------------------------------------------------------------------------------------------------------------------2 rows in set, 1 warning (0.03 sec)UNIONUNION中的第二个或后面的SELECT语句mysql explain select * from t_a where id 9 union all select * from t_a;----------------------------------------------------------------------------------------------------------------| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |----------------------------------------------------------------------------------------------------------------| 1 | PRIMARY | t_a | NULL | const | PRIMARY | PRIMARY | 8 | const | 1 | 100.00 | NULL || 2 | UNION | t_a | NULL | index | NULL | num_key | 5 | NULL | 9 | 100.00 | Using index |----------------------------------------------------------------------------------------------------------------2 rows in set, 1 warning (0.04 sec)DEPENDENT UNIONUNION中的第二个或以后的SELECT语句取决于外部查询mysql explain select * from t_a where id in (select id from t_a where id 8 union all select id from t_a where id 5);-------------------------------------------------------------------------------------------------------------------------------------| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |-------------------------------------------------------------------------------------------------------------------------------------| 1 | PRIMARY | t_a | NULL | index | NULL | num_key | 5 | NULL | 9 | 100.00 | Using where; Using index || 2 | DEPENDENT SUBQUERY | t_a | NULL | eq_ref | PRIMARY | PRIMARY | 8 | func | 1 | 100.00 | Using where; Using index || 3 | DEPENDENT UNION | t_a | NULL | const | PRIMARY | PRIMARY | 8 | const | 1 | 100.00 | Using index |-------------------------------------------------------------------------------------------------------------------------------------3 rows in set, 1 warning (0.08 sec)UNION RESULTUNION的结果mysql explain select num from t_a where id 3 union select num from t_a where id 4;--------------------------------------------------------------------------------------------------------------------------| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |--------------------------------------------------------------------------------------------------------------------------| 1 | PRIMARY | t_a | NULL | const | PRIMARY | PRIMARY | 8 | const | 1 | 100.00 | NULL || 2 | UNION | t_a | NULL | const | PRIMARY | PRIMARY | 8 | const | 1 | 100.00 | NULL || NULL | UNION RESULT | | NULL | ALL | NULL | NULL | NULL | NULL | NULL | NULL | Using temporary |--------------------------------------------------------------------------------------------------------------------------3 rows in set, 1 warning (0.03 sec)SUBQUERY子查询中的第一个选择mysql explain select * from t_a where num (select num from t_a where id 3);-----------------------------------------------------------------------------------------------------------------------------| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |-----------------------------------------------------------------------------------------------------------------------------| 1 | PRIMARY | t_a | NULL | range | num_key | num_key | 5 | NULL | 6 | 100.00 | Using where; Using index || 2 | SUBQUERY | t_a | NULL | const | PRIMARY | PRIMARY | 8 | const | 1 | 100.00 | NULL |-----------------------------------------------------------------------------------------------------------------------------2 rows in set, 1 warning (0.03 sec)DEPENDENT SUBQUERY子查询中的第一个选择取决于外部查询mysql explain select * from t_a where num in(select num from t_a where id 3 union select num from t_a where id 4);-------------------------------------------------------------------------------------------------------------------------------------------| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |-------------------------------------------------------------------------------------------------------------------------------------------| 1 | PRIMARY | t_a | NULL | index | NULL | num_key | 5 | NULL | 9 | 100.00 | Using where; Using index || 2 | DEPENDENT SUBQUERY | t_a | NULL | const | PRIMARY,num_key | PRIMARY | 8 | const | 1 | 100.00 | NULL || 3 | DEPENDENT UNION | t_a | NULL | const | PRIMARY,num_key | PRIMARY | 8 | const | 1 | 100.00 | NULL || NULL | UNION RESULT | | NULL | ALL | NULL | NULL | NULL | NULL | NULL | NULL | Using temporary |-------------------------------------------------------------------------------------------------------------------------------------------4 rows in set, 1 warning (0.12 sec)DERIVED派生表(子查询中产生的临时表)mysql explain select a.id from (select id from t_a where id 8 union all select id from t_a where id 5) a;----------------------------------------------------------------------------------------------------------------------------------| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |----------------------------------------------------------------------------------------------------------------------------------| 1 | PRIMARY | | NULL | ALL | NULL | NULL | NULL | NULL | 3 | 100.00 | NULL || 2 | DERIVED | t_a | NULL | range | PRIMARY | PRIMARY | 8 | NULL | 1 | 100.00 | Using where; Using index || 3 | UNION | t_a | NULL | const | PRIMARY | PRIMARY | 8 | const | 1 | 100.00 | Using index |----------------------------------------------------------------------------------------------------------------------------------3 rows in set, 1 warning (0.12 sec)2.3 table显示这一行的数据是关于哪张表的有时是真实的表名字有时也可能是以下几种结果: 指id为M,N行结果的并集: 该行是指id值为n的行的派生表结果。派生表可能来自例如from子句中的子查询。: 该行是指id值为n的行的物化子查询的结果。2.4 partitions查询的记录所属于的分区对于未分区表该值为NULL。2.5 type连接使用了哪种类别,有无使用索引,常用的类型有system, const, eq_ref, ref, range, index, ALL(从左到右性能越来越差)详情查看EXPLAIN Join TypesNULLMySQL在优化过程中分解语句执行时甚至不用访问表或索引例如从一个索引列里选取最小值可以通过单独索引查找完成system这个表(也可能是查询出来的临时表)只有一行数据 ( system table). 是const中的一个特例const表最多有一个匹配行它将在查询开始时被读取。因为仅有一行在这行的列值可被优化器剩余部分认为是常数。const表很快因为它们只读取一次const用于查询条件为PRIMARY KEY或UNIQUE索引并与常数值进行比较时的所有部分。在下面的查询中tbl_name可以用于const表SELECT * from tbl_name WHERE primary_key1SELECT * from tbl_name WHERE primary_key_part11和 primary_key_part22--例子mysql explain select * from t_a where id 1;----------------------------------------------------------------------------------------------------------| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |----------------------------------------------------------------------------------------------------------| 1 | SIMPLE | t_a | NULL | const | PRIMARY | PRIMARY | 8 | const | 1 | 100.00 | NULL |----------------------------------------------------------------------------------------------------------1 row in set, 1 warning (0.07 sec)eq_ref对于前几个表中的每一行组合从该表中读取一行。除了system和const这是最好的连接类型。当连接使用索引的所有部分并且索引是主键或唯一非空索引时将使用它。eq_ref可以用于使用 操作符比较的带索引的列。比较值可以为常量或一个使用在该表前面所读取的表的列的表达式。在下面的例子中MySQL可以使用eq_ref联接去处理ref_tablesSELECT * FROM ref_table,other_tableWHERE ref_table.key_columnother_table.column;SELECT * FROM ref_table,other_tableWHERE ref_table.key_column_part1other_table.columnAND ref_table.key_column_part21;--例子(t_b为t_a的复制表表结构相同)mysql explain select * from t_a,t_b where t_a.codet_b.code;-------------------------------------------------------------------------------------------------------------------| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |-------------------------------------------------------------------------------------------------------------------| 1 | SIMPLE | t_a | NULL | ALL | uk_code | NULL | NULL | NULL | 9 | 100.00 | NULL || 1 | SIMPLE | t_b | NULL | eq_ref | uk_code | uk_code | 4 | test.t_a.code | 1 | 100.00 | NULL |-------------------------------------------------------------------------------------------------------------------2 rows in set, 1 warning (0.03 sec)ref对于每个来自于前面的表的行组合所有有匹配索引值的行将从这张表中读取。如果联接只使用键的最左边的前缀或如果键不是UNIQUE或PRIMARY KEY(换句话说如果联接不能基于关键字查询结果为单个行的话)则使用ref。如果使用的键仅仅匹配少量行该联接类型是不错的。ref可以用于使用或操作符的带索引的列。在下面的例子中MySQL可以使用ref联接来处理ref_tablesSELECT * FROM ref_table WHERE key_columnexpr;SELECT * FROM ref_table,other_tableWHERE ref_table.key_columnother_table.column;SELECT * FROM ref_table,other_tableWHERE ref_table.key_column_part1other_table.columnAND ref_table.key_column_part21;--例子(t_b为t_a的复制表表结构相同)mysql explain select * from t_a,t_b where t_a.aget_b.age;----------------------------------------------------------------------------------------------------------------------| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |----------------------------------------------------------------------------------------------------------------------| 1 | SIMPLE | t_a | NULL | ALL | age_key | NULL | NULL | NULL | 9 | 100.00 | Using where || 1 | SIMPLE | t_b | NULL | ref | age_key | age_key | 5 | test.t_a.age | 1 | 100.00 | NULL |----------------------------------------------------------------------------------------------------------------------2 rows in set, 1 warning (0.03 sec)fulltext使用FULLTEXT索引执行连接ref_or_null该联接类型ref类似但是添加了MySQL可以专门搜索包含NULL值的行。在解决子查询中经常使用该联接类型的优化。在下面的例子中MySQL可以使用ref_or_null联接来处理ref_tablesSELECT * FROM ref_tableWHERE key_columnexpr OR key_column IS NULL;--例子mysql explain select * from t_a where t_a.age 3 or t_a.age is null;--------------------------------------------------------------------------------------------------------------------------------| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |--------------------------------------------------------------------------------------------------------------------------------| 1 | SIMPLE | t_a | NULL | ref_or_null | age_key | age_key | 5 | const | 2 | 100.00 | Using index condition |--------------------------------------------------------------------------------------------------------------------------------1 row in set, 1 warning (0.03 sec)index_merge该联接类型表示使用了索引合并优化方法。在这种情况下key列包含了使用的索引的清单key_len包含了使用的索引的最长的关键元素。SELECT * FROM ref_tableWHERE idx1expr1 OR idx2 expr2;--例子mysql explain select * from t_a where t_a.code 3 or t_a.age 3;-------------------------------------------------------------------------------------------------------------------------------------------------------------| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |-------------------------------------------------------------------------------------------------------------------------------------------------------------| 1 | SIMPLE | t_a | NULL | index_merge | uk_code,age_key | uk_code,age_key | 4,5 | NULL | 2 | 100.00 | Using union(uk_code,age_key); Using where |-------------------------------------------------------------------------------------------------------------------------------------------------------------1 row in set, 1 warning (0.03 sec)unique_subquery该类型替换了下面形式的IN子查询的refvalue IN (SELECT primary_key FROM single_table WHERE some_expr)unique_subquery是一个索引查找函数可以完全替换子查询效率更高。index_subquery该联接类型类似于unique_subquery。可以替换IN子查询但只适合下列形式的子查询中的非唯一索引value IN (SELECT key_column FROM single_table WHERE some_expr)range只检索给定范围的行使用一个索引来选择行。key列显示使用了哪个索引。key_len包含所使用索引的最长关键元素。在该类型中ref列为NULL。当使用、、、、、BETWEEN或者IN操作符用常量比较关键字列时可以使用rangemysql explain select * from t_a where id 8;---------------------------------------------------------------------------------------------------------------| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |---------------------------------------------------------------------------------------------------------------| 1 | SIMPLE | t_a | NULL | range | PRIMARY | PRIMARY | 8 | NULL | 1 | 100.00 | Using where |---------------------------------------------------------------------------------------------------------------1 row in set, 1 warning (0.03 sec)index该联接类型与ALL相同除了只有索引树被扫描。这通常比ALL快因为索引文件通常比数据文件小。当查询只使用作为单索引一部分的列时MySQL可以使用该联接类型。ALL对于每个来自于先前的表的行组合进行完整的表扫描。如果表是第一个没标记const的表这通常不好并且通常在它情况下很差。通常可以增加更多的索引而不要使用ALL使得行能基于前面的表中的常数值或列值被检索出。2.6 possible_keyspossible_keys列指出MySQL能使用哪个索引在该表中找到行。注意该列完全独立于EXPLAIN输出所示的表的次序。这意味着在possible_keys中的某些键实际上不能按生成的表次序使用。如果该列是NULL则没有相关的索引。在这种情况下可以通过检查WHERE子句看是否它引用某些列或适合索引的列来提高你的查询性能。如果是这样创造一个适当的索引并且再次用EXPLAIN检查查询2.7 keykey列显示MySQL实际决定使用的键(索引)。如果没有选择索引键是NULL。要想强制MySQL使用或忽视possible_keys列中的索引在查询中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。2.8 key_lenkey_len列显示MySQL决定使用的键长度。如果键是NULL则长度为NULL。使用的索引的长度。在不损失精确性的情况下长度越短越好2.9 refref列显示使用哪个列或常数与key一起从表中选择行。2.10 rowsrows列显示MySQL认为它执行查询时必须检查的行数。2.11 Extra该列包含MySQL解决查询的详细信息,下面详细.Distinct一旦MYSQL找到了与行相联合匹配的行就不再搜索了Not existsMYSQL优化了LEFT JOIN一旦它找到了匹配LEFT JOIN标准的行就不再搜索了Range checked for each没有找到理想的索引因此对于从前面表中来的每一个行组合MYSQL检查使用哪个索引并用它来从表中返回行。这是使用索引的最慢的连接之一Using filesort看到这个的时候查询就需要优化了。MYSQL需要进行额外的步骤来发现如何对返回的行排序。它根据连接类型以及存储排序键值和匹配条件的全部行的行指针来排序全部行Using index列数据是从仅仅使用了索引中的信息而没有读取实际的行动的表返回的这发生在对表的全部的请求列都是同一个索引的部分的时候Using temporary看到这个的时候查询需要优化了。这里MYSQL需要创建一个临时表来存储结果这通常发生在对不同的列集进行ORDER BY上而不是GROUP BY上Using where使用了WHERE从句来限制哪些行将与下一张表匹配或者是返回给用户。如果不想返回表中的全部行并且连接类型ALL或index这就会发生或者是查询有问题参考