MySQL执行计划
查看索引:
mysql> show index from user_info; +-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | +-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | user_info | 0 | PRIMARY | 1 | id | A | 6 | NULL | NULL | | BTREE | | | +-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 1 row in set
查看键:
mysql> show keys from user_info; +-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | +-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | user_info | 0 | PRIMARY | 1 | id | A | 6 | NULL | NULL | | BTREE | | | +-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 1 row in set
查看语句的耗时:
mysql> set profiling = 1; Query OK, 0 rows affected mysql> select * from word_list where word like 'b%'; +-----------+-----------------------------------------------+------+ | word | paraphrase | sign | +-----------+-----------------------------------------------+------+ | backward | a. 向后的; ad. 向后 | F | | bar | vt. 1.阻止,不许 2.阻碍,阻塞 n. 酒吧,吧台 | F | | being | n. 1.生物,人 2.存在 | F | | billboard | n. 布告板,揭示栏,广告牌 | F | | billion | num.&n. 十亿 | F | | butterfly | n. 蝴蝶 | F | +-----------+-----------------------------------------------+------+ 6 rows in set mysql> select * from word_list where word like 'c%'; +----------------+----------------------------------+------+ | word | paraphrase | sign | +----------------+----------------------------------+------+ | capital-driven | a. 追求更多资本的 | F | | cartoon | n. 动画片; vt. 为...画漫画 | T | | chart | n. 图,图表 vt. 制图表 | F | | cholesterol | n. 胆固醇 | F | | circuit | n. 电路,一圈,巡回 | F | | civil | a. 国内的,公民的,国民的 | F | | civilization | n. 文明,文化 | F | | classical | a. 古典的 | F | | colonial | a. 殖民地的; n. 殖民地居民 | F | | colonialism | n. 殖民主义 | F | | commercial | a. 商业的; n. 商业广告 | F | | comparison | n. 比较 | F | | competition | n. 比赛,竞争 | F | | competitive | a. 竞争的,比赛的 | F | | compute | 计算 | F | | conference | n. 会议 | F | | confine | v. 限制,闭居; [计算机] 限制 | F | | congress | n. 代表大会,国会,议会;男女性交 | F | | consequence | ad. 因而,所以; n. 结果,后果 | F | | constant | a. 经常的,不变的; n. 常数,恒量 | F | | constantly | ad. 不断地,经常地 | F | | construct | v. 构造,建造,想出 | F | | constructive | a. 建设性的,构造上的,作图的 | F | | consumeristic | adj. 消费主义的 | F | | consumption | n. 消费 | F | | contribution | n. 贡献 | F | | cooperate | vi. 合作,协作,配合 | F | | corporation | n. 公司 | F | | cycle | n. 循环,周期; v. 骑自行车 | F | +----------------+----------------------------------+------+ 29 rows in set mysql> show profiles; +----------+------------+----------------------------------------------+ | Query_ID | Duration | Query | +----------+------------+----------------------------------------------+ | 1 | 0.00065 | select * from word_list where word like 'b%' | | 2 | 0.00047325 | select * from word_list where word like 'c%' | +----------+------------+----------------------------------------------+ 2 rows in set
Explain
mysql> explain select * from epsp_express_post_freight_config where service_point_code in (select service_point_code from epsp_express_post_freight_config where express_company_id = 'SF'); +----+--------------+----------------------------------+------------+------+---------------+-------+---------+--------------------------------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+--------------+----------------------------------+------------+------+---------------+-------+---------+--------------------------------+------+----------+-------------+ | 1 | SIMPLE | <subquery2> | NULL | ALL | NULL | NULL | NULL | NULL | NULL | 100.00 | Using where | | 1 | SIMPLE | epsp_express_post_freight_config | NULL | ref | idx_a | idx_a | 93 | <subquery2>.service_point_code | 1 | 100.00 | NULL | | 2 | MATERIALIZED | epsp_express_post_freight_config | NULL | ALL | idx_a | NULL | NULL | NULL | 741 | 10.00 | Using where | +----+--------------+----------------------------------+------------+------+---------------+-------+---------+--------------------------------+------+----------+-------------+ 3 rows in set (0.02 sec)
1. select_type
SIMPLE:简单SELECT(不使用UNION或子查询)
mysql> explain select * from epsp_express_post_freight_config where id = 405348; +----+-------------+----------------------------------+------------+-------+---------------+---------+---------+-------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+----------------------------------+------------+-------+---------------+---------+---------+-------+------+----------+-------+ | 1 | SIMPLE | epsp_express_post_freight_config | NULL | const | PRIMARY | PRIMARY | 8 | const | 1 | 100.00 | NULL | +----+-------------+----------------------------------+------------+-------+---------------+---------+---------+-------+------+----------+-------+ 1 row in set (0.02 sec)
PRIMARY:最外面的SELECT(如两表做UNION或者存在子查询的外层的表操作为PRIMARY,内层的操作为UNION)
mysql> explain select * from epsp_express_post_freight_config where id = (select max(id) from epsp_express_post_freight_config); +----+-------------+----------------------------------+------------+-------+---------------+---------+---------+-------+------+----------+------------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+----------------------------------+------------+-------+---------------+---------+---------+-------+------+----------+------------------------------+ | 1 | PRIMARY | epsp_express_post_freight_config | NULL | const | PRIMARY | PRIMARY | 8 | const | 1 | 100.00 | NULL | | 2 | SUBQUERY | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Select tables optimized away | +----+-------------+----------------------------------+------------+-------+---------------+---------+---------+-------+------+----------+------------------------------+ 2 rows in set (0.03 sec)
UNION:UNION中的第二个或后面的SELECT语句
mysql> explain select max(id) from epsp_express_post_freight_config UNION select min(id) from epsp_express_post_freight_config; +------+--------------+------------+------------+------+---------------+------+---------+------+------+----------+------------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +------+--------------+------------+------------+------+---------------+------+---------+------+------+----------+------------------------------+ | 1 | PRIMARY | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Select tables optimized away | | 2 | UNION | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Select tables optimized away | | NULL | UNION RESULT | <union1,2> | NULL | ALL | NULL | NULL | NULL | NULL | NULL | NULL | Using temporary | +------+--------------+------------+------------+------+---------------+------+---------+------+------+----------+------------------------------+ 3 rows in set (0.03 sec)
DEPENDENT UNION:UNION中的第二个或后面的SELECT语句,取决于外面的查询(此处的dependent表示union或union all联合而成的单位查询受外部影响)
mysql> explain select e.id from epsp_express_post_freight_config e where e.id in (select a.id from epsp_express_post_freight_config a where a.id < 1000 UNION select b.id from epsp_express_post_freight_config b where b.id > 5000); +------+--------------------+------------+------------+--------+---------------+---------+---------+------+------+----------+--------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +------+--------------------+------------+------------+--------+---------------+---------+---------+------+------+----------+--------------------------+ | 1 | PRIMARY | e | NULL | index | NULL | idx_a | 93 | NULL | 741 | 100.00 | Using where; Using index | | 2 | DEPENDENT SUBQUERY | a | NULL | eq_ref | PRIMARY | PRIMARY | 8 | func | 1 | 100.00 | Using where; Using index | | 3 | DEPENDENT UNION | b | NULL | eq_ref | PRIMARY | PRIMARY | 8 | func | 1 | 100.00 | Using where; Using index | | NULL | UNION RESULT | <union2,3> | NULL | ALL | NULL | NULL | NULL | NULL | NULL | NULL | Using temporary | +------+--------------------+------------+------------+--------+---------------+---------+---------+------+------+----------+--------------------------+ 4 rows in set (0.05 sec) mysql> show warnings; +-------+------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Level | Code | Message | +-------+------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Note | 1003 | /* select#1 */ select `mytest`.`e`.`id` AS `id` from `mytest`.`epsp_express_post_freight_config` `e` where <in_optimizer>(`mytest`.`e`.`id`,<exists>(/* select#2 */ select 1 from `mytest`.`epsp_express_post_freight_config` `a` where ((`mytest`.`a`.`id` < 1000) and (<cache>(`mytest`.`e`.`id`) = `mytest`.`a`.`id`)) union /* select#3 */ select 1 from `mytest`.`epsp_express_post_freight_config` `b` where ((`mytest`.`b`.`id` > 5000) and (<cache>(`mytest`.`e`.`id`) = `mytest`.`b`.`id`)))) | +-------+------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.04 sec)
UNION RESULT:UNION 的结果
SUBQUERY:子查询中的第一个SELECT
DEPENDENT SUBQUERY:子查询中的第一个SELECT,取决于外面的查询
DERIVED:导出表的SELECT(FROM子句的子查询)
MATERIALIZED:被物化的子查询
2. partitions
如果查询是基于分区表的话,显示查询将访问的分区。
3. type
system:表仅有一行(系统表)。这是const联接类型的一个特例。
const:表最多有一个匹配行,它将在查询开始时被读取。因为仅有一行,在这行的列值可被优化器剩余部分认为是常数。const表很快,因为它们只读取一次!
mysql> explain select * from epsp_express_post_freight_config where id = 405348; +----+-------------+----------------------------------+------------+-------+---------------+---------+---------+-------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+----------------------------------+------------+-------+---------------+---------+---------+-------+------+----------+-------+ | 1 | SIMPLE | epsp_express_post_freight_config | NULL | const | PRIMARY | PRIMARY | 8 | const | 1 | 100.00 | NULL | +----+-------------+----------------------------------+------------+-------+---------------+---------+---------+-------+------+----------+-------+ 1 row in set (0.02 sec)
eq_ref:唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配,常用于主键或唯一索引扫描
ref:对于每个来自于前面的表的行组合,所有有匹配索引值的行将从这张表中读取。
mysql> explain select * from epsp_express_post_freight_config where service_point_code = 'FC551Z000007'; +----+-------------+----------------------------------+------------+------+---------------+-------+---------+-------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+----------------------------------+------------+------+---------------+-------+---------+-------+------+----------+-------+ | 1 | SIMPLE | epsp_express_post_freight_config | NULL | ref | idx_a | idx_a | 93 | const | 6 | 100.00 | NULL | +----+-------------+----------------------------------+------------+------+---------------+-------+---------+-------+------+----------+-------+ 1 row in set (0.03 sec)
ref_or_null:该联接类型如同ref,但是添加了MySQL可以专门搜索包含NULL值的行。
index_merge:该联接类型表示使用了索引合并优化方法。
unique_subquery:该类型替换了下面形式的IN子查询的ref: value 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:只检索给定范围的行,使用一个索引来选择行。
mysql> explain select * from epsp_express_post_freight_config where id > 1000; +----+-------------+----------------------------------+------------+-------+---------------+---------+---------+------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+----------------------------------+------------+-------+---------------+---------+---------+------+------+----------+-------------+ | 1 | SIMPLE | epsp_express_post_freight_config | NULL | range | PRIMARY | PRIMARY | 8 | NULL | 370 | 100.00 | Using where | +----+-------------+----------------------------------+------------+-------+---------------+---------+---------+------+------+----------+-------------+ 1 row in set (0.02 sec)
index:全索引扫描,只遍历索引树。这通常比ALL快,因为索引文件通常比数据文件小。
mysql> explain select id from epsp_express_post_freight_config; +----+-------------+----------------------------------+------------+-------+---------------+-------+---------+------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+----------------------------------+------------+-------+---------------+-------+---------+------+------+----------+-------------+ | 1 | SIMPLE | epsp_express_post_freight_config | NULL | index | NULL | idx_a | 93 | NULL | 741 | 100.00 | Using index | +----+-------------+----------------------------------+------------+-------+---------------+-------+---------+------+------+----------+-------------+ 1 row in set (0.03 sec)
ALL:全表扫描,找到匹配行。与index比较,ALL需要扫描磁盘数据,index值需要遍历索引树。
一般来说,得保证查询至少达到range级别,最好能达到ref。
4. possible_keys
指出MySQL能使用哪个索引在该表中找到行
5. key
显示MySQL实际决定使用的键(索引)。如果没有选择索引,是NULL。
6. key_len
显示MySQL决定使用的键长度。如果键是NULL,则长度为NULL。在不损失精确性的情况下,长度越短越好
7. ref
显示使用哪个列或常数与key一起从表中选择行。即哪些列或常量被用于查找索引列上的值
8. rows
表示MySQL根据表统计信息及索引选用情况,估算的找到所需的记录所需要读取的行数
9. filtered
显示了通过条件过滤出的行数的百分比估计值。
10. Extra
Distinct:MySQL发现第1个匹配行后,停止为当前的行组合搜索更多的行。
Select tables optimized away MySQL根本没有遍历表或索引就返回数据了,表示已经优化到不能再优化了
Not exists:MySQL能够对查询进行LEFT JOIN优化,发现1个匹配LEFT JOIN标准的行后,不再为前面的的行组合在该表内检查更多的行。
range checked for each record (index map: #):MySQL没有发现好的可以使用的索引,但发现如果来自前面的表的列值已知,可能部分索引可以使用。
Using filesort:MySQL需要额外的一次传递,以找出如何按排序顺序检索行,说明查询就需要优化了。
Using index:从只使用索引树中的信息而不需要进一步搜索读取实际的行来检索表中的列信息。
Using temporary:为了解决查询,MySQL需要创建一个临时表来容纳结果,说明查询就需要优化了。
Using where:WHERE 子句用于限制哪一个行匹配下一个表或发送到客户。
Using sort_union(...), Using union(...), Using intersect(...):这些函数说明如何为index_merge联接类型合并索引扫描。
Using index for group-by:类似于访问表的Using index方式,Using index for group-by表示MySQL发现了一个索引,可以用来查 询GROUP BY或DISTINCT查询的所有列,而不要额外搜索硬盘访问实际的表。