mysql性能查询关键字_高性能mysqlMySQL_explain关键字分析查询语句(一)

通过对查询语句的分析,可以了解查询语句的执行情况。MySQL中,可以使用EXPLAIN语句和DESCRIBE语句来分析查询语句。

EXPLAIN语句的基本语法如下:(DESCRIBE语法一致,DESCRIBE可简写为DESC)

EXPLAIN Select 语句;

eg:explain SELECT * FROM `user` where name = 'name6'; 结果如下:

117841ab12e955b572f2a32501e50a07.png

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

表示查询使用到的索引;

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

语句1

1

SIMPLE

user

const

name_unidx

name_unidx

32

const

1

null

语句2

1

SIMPLE

user_noindex

ALL

null

null

null

null

10

Using 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

语句1

1

SIMPLE

user

ALL

null

null

null

null

10

Using where

语句2

1

SIMPLE

user

ALL

null

null

null

null

10

Using where

语句3

1

SIMPLE

user

range

name_unidx

name_unidx

32

const

1

null

【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

语句1

1

SIMPLE

user

ref

index_age_sex

index_age_sex

4

const

1

null

语句2

1

SIMPLE

user

ALL

null

null

null

null

10

Using where

语句3

1

SIMPLE

user

ref

index_age_sex

index_age_sex

5

const,const

1

null

【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

语句1

1

SIMPLE

user

ALL

index_age_sex

null

null

null

10

Using where

语句2

1

SIMPLE

user

ALL

index_age_sex

null

null

null

10

Using where

语句3

1

SIMPLE

user

ref

PRIMARY,id_unidx,name_unidx

index_age_sex

null

null

10

Using where

-- alter table user engine = myisam;

结果集

id

select_type

table

type

possible_keys

key

key_len

ref

rows

Extra

语句1

1

SIMPLE

user

ALL

index_age_sex

null

null

null

10

Using where

语句2

1

SIMPLE

user

ALL

index_age_sex

null

null

null

10

Using where

语句3

1

SIMPLE

user

index_merge

PRIMARY,

id_unidx,

name_unidx

name_unidx,

PRIMARY

32,4

null

2

Using union

(name_unidx,PRIMARY);

Using where

很多查询中需要使用子查询。子查询可以使查询语句很灵活,但子查询的执行效率不高。子查询时,MySQL需要为内层查询语句的查询结果建立一个临时表。然后外层查询语句在临时表中查询记录。查询完毕后,MySQL需要撤销这些临时表。因此,子查询的速度会受到一定的影响。如果查询的数据量比较大,这种影响就会随之增大。在MySQL中可以使用连接查询来替代子查询。连接查询不需要建立临时表,其速度比子查询要快。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值