MySQL_explain关键字分析查询语句
版权声明:本⽂为博主原创⽂章,转载请注明出处。
通过对查询语句的分析,可以了解查询语句的执⾏情况。MySQL中,可以使⽤EXPLAIN语句和DESCRIBE语句来分析查询语句。 EXPLAIN语句的基本语法如下:(DESCRIBE语法⼀致,DESCRIBE可简写为DESC)
EXPLAIN Select 语句;
eg:explain SELECT * FROM `user` where name = 'name6'; 结果如下:
explain结果值及其含义:
参数值含义
id表⽰SELECT语句的编号;
select_type 表⽰SELECT语句的类型。
该参数有⼏个常⽤的取值:
SIMPLE :表⽰简单查询,其中不包括连接查询和⼦查询; PRIMARY:表⽰主查询,或者是最外层的查询语句; UNION :表⽰连接查询的第⼆个或后⾯的查询语句;
table表⽰查询的表;
type 表⽰表的连接类型。该参数有⼏个常⽤的取值:
const :表⽰表中有多条记录,但只从表中查询⼀条记录;
eq_ref :表⽰多表连接时,后⾯的表使⽤了UNIQUE或者PRIMARY KEY;
ref :表⽰多表查询时,后⾯的表使⽤了普通索引;
unique_ subquery:表⽰⼦查询中使⽤了UNIQUE或者PRIMARY KEY;
index_ subquery:表⽰⼦查询中使⽤了普通索引; range :表⽰查询语句中给出了查询范围; index :表⽰对表中的索引进⾏了完整的扫描;
all :表⽰此次查询进⾏了全表扫描; ----------- 该条SQL需要优化;
possible_keys 表⽰查询中可能使⽤的索引;
如果备选的数量⼤于3那说明已经太多了,因为太多会导致选择索引⽽损耗性能,所以建表时字段最好精简,同时也要建⽴联合索引,避免⽆效的单列索引;
key表⽰查询使⽤到的索引;
简单的mysql语句key_len表⽰索引字段的⼀长度;
ref表⽰使⽤哪个列或常数与索引⼀起来查询记录;
rows 表⽰查询的⾏数;
试图分析所有存在于累计结果集中的⾏数,虽然只是⼀个估值,却也⾜以反映出SQL执⾏所需要扫描的⾏数,因此这个值越⼩越好;
Extra表⽰查询过程的附件信息。
通过explain可以得到如下结论:
①使⽤索引⽐未使⽤索引,扫描的⾏数更少查询速度更快;
②在查询语句中使⽤LIKE关键字进⾏查询时,如果匹配字符串的第⼀个字符为“%”时,索引不会被使⽤。如果“%”不是在第⼀个位置,索引就会被使⽤。
③使⽤多列索引时,只有查询条件中使⽤了该索引中的第⼀个索引字段时,索引才会被使⽤。
注:create index index_age_sex on user(age,sex); age为第⼀个索引;
④查询语句只有OR关键字时,如果OR前后的两个条件列都是索引时,查询中将使⽤索引。只要OR前后有⼀个条件的列不是索引,那么查询中将不使⽤索引。
注: 1:where 语句⾥⾯如果带有or条件, myisam表能⽤到索引,innodb不⾏;2:必须所有的or条件都必须是独⽴索引;
⑤经过普通运算或函数运算后的索引字段不能使⽤索引。
但是,经过函数运算字段的字段要使⽤可以使⽤函数索引,这种需求建议与DBA沟通。
以上结论来⾃如下测试:
user表:独⽴索引:id、name 联合索引:age && sex user_noindex表:⽆任何索引列;
CREATE TABLE `user` ( `id` int(11) NOT NULL, `name` varchar(30) NOT NULL, `age` int(11) NOT NULL, `sex` tinyint(4) NOT NULL, `isDeleted` tinyint(4) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `id_unidx` (`id`) USING BTREE, UNIQUE KEY `name_unidx` (`name`) USING BTREE, KEY `index_age_sex` (`age`,`sex`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;CREATE TABLE `user_noindex` ( `id` int(11) NOT NULL, `name` varchar(30) NOT NULL, `age` int(11) DEFAULT NULL, `sex` tinyint(4) DEFAULT NULL, `isDeleted` tinyint(4) DEFAULT NULL )
ENGINE=InnoDB DEFAULT CHARSET=utf8;
【1】索引对查询的影响-----加索引和不加索引的对⽐-----使⽤索引扫描的更少查询更快
语句1:explain SELECT * FROM `user` where name = 'name6';
语句2:explain SELECT * FROM `user_noindex` where name = 'name6';
结果集id select_type table type possible_keys key key_len ref rows Extra
语句11SIMPLE user constname_unidx name_unidx32const1null
语句21SIMPLE user_noindex ALL null null null null10Using where
【2】索引对查询的影响-----加索引----使⽤和未使⽤索引的对⽐-----在查询语句中使⽤LIKE关键字进⾏查询时,如果匹配字符串的第⼀个字符为“%”时,索引不会被使⽤。如果“%”不是在第⼀个位置,索引就会被使⽤。
语句1:explain SELECT * FROM `user` where name like '%name6';
语句2:explain SELECT * FROM `user` where name like '%name6%';
语句3:explain SELECT * FROM `user` where name like 'name6%';
结果集id select_type table type possible_keys key key_len ref rows Extra
语句11SIMPLE user ALL null null null null10Using where
语句21SIMPLE user ALL null null null null10Using where
语句31SIMPLE user range name_unidx name_unidx32const1null
【3】索引对查询的影响-----加索引----使⽤和未使⽤索引的对⽐-----多列索引是在表的多个字段创建
⼀个索引。只有查询条件中使⽤了这个字段中的第⼀个字段时,索引才会被使⽤。
语句1:explain SELECT * FROM `user` where age = '19';
语句2:explain SELECT * FROM `user` where sex = '1';
语句3:explain SELECT * FROM `user` where sex = '1' and age = '19';
结果集id select_type table type possible_keys key key_len ref rows Extra
语句11SIMPLE user ref index_age_sex index_age_sex4const1null
语句21SIMPLE user ALL null null null null10Using where
语句31SIMPLE user ref index_age_sex index_age_sex5const,const1null
【4】索引对查询的影响-----加索引----使⽤和未使⽤索引的对⽐-----查询语句只有OR关键字时,如果OR前后的两个条件的列都是索引时,查询中将使⽤索引。如果OR前后有⼀个条件的列不是索引,那么查询中将不使⽤索引。
语句1:explain SELECT * FROM `user` where (age = '19' OR isDeleted = '0');
语句2:explain SELECT * FROM `user` where (sex = '1' OR age = '19'); -- 联合索引
语句3:explain SELECT * FROM `user` where (name = 'name1' OR id = '1'); -- 独⽴索引
-- alter table user engine = innodb;
结果集id select_type table type possible_keys key key_len ref rows Extra
语句11SIMPLE user ALL index_age_sex null null null10Using where
语句21SIMPLE user ALL index_age_sex null null null10Using where
语句31SIMPLE user ref PRIMARY,id_unidx,name_unidx index_age_sex null null10Using where
-- alter table user engine = myisam;
结果集id select_type table type possible_keys key key_len ref rows Extra
语句11SIMPLE user ALL index_age_sex null null null10Using where 语句21SIMPLE user ALL index_age_sex null null null10Using where
语句31SIMPLE user index_merge PRIMARY,
id_unidx,
name_unidx
name_unidx,
PRIMARY
32,4null2
Using union
(name_unidx,PRIMARY);
Using where
很多查询中需要使⽤⼦查询。⼦查询可以使查询语句很灵活,但⼦查询的执⾏效率不⾼。⼦查询时,MySQL需要为内层查询语句的查询结果建⽴⼀个临时表。然后外层查询语句在临时表中查询记录。查询完毕后,MySQL需要撤销这些临时表。因此,⼦查询的速度会受到⼀定的影响。如果查询的数据量⽐较⼤,这种影响就会随之增⼤。在MySQL中可以使⽤连接查询来替代⼦查询。连接查询不需要建⽴临时表,其速度⽐⼦查询要快。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论