Mysql数据库优化—2

注意:(针对mysql5.5版本,其他版本可能略有差异)

一、explain关键字解析

1、explain的id和table分析

情景:

要求:查询教sql课程的老师描述

①、sql:

select tc.tcdesc from teacherCard tc,course c,teacher t where c.tid = t.tid and t.tcid = tc.tcid and c.cname = 'sql';

②、使用explain

③、将上述的sql改为子查询

select tc.tcdesc from teacherCard tc where tc.tcid=
    (select t.tcid from teacher t where t.tid=
        (select c.tid from course c where c.cname='sql')
    );

结论:当id不相同时,id越大越先执行,即先c——>t——>tc

④、将上述sql改为多表+子查询的方式

select tc.tcdesc from teacherCard tc,teacher t where t.tcid = tc.tcid and t.tid = (select c.tid from course c where c.cname = 'sql');

结论:当id有相同又有不相同时,先执行id大的,id相同的顺序执行

总结:当id相同时,顺序执行;当id不同时,id大的先执行

 

2、select_type分析

PRIMARY:包含子查询SQL中的 主查询 (最外层)
SUBQUERY:包含子查询SQL中的 子查询 (非最外层)
simple:简单查询(不包含子查询、union)
derived:衍生查询(使用到了临时表)

①、在from子查询中只有一张表
               explain select  tmp.cname     from ( select * from course where tid in (1,2) ) tmp;

PRIMARY后面的table为derived2说明其使用衍生表进行查询,其id为2。

②、在from子查询中,如果有table1 union table2,则table1就是derived,table2就是union

explain select  cr.cname 	from ( select * from course where tid = 1  union select * from course where tid = 2 ) cr ;

union:如上例

union result :告知开发人员,那些表之间存在union查询

 

3、type分析

type的类型:system>const>eq_ref>ref>range>index>all 对type优化的前提是:有索引

①、system:只有一条数据的系统表;或者衍生表只有一条数据的主查询

create table test1(
    tid int,
    tname varchar(20)

);
insert into test1 values(1,'001');

--增加主键索引
alter table test1 add constraint tid_pk primary key(tid);

explain select * from (select * from test1) t where tid = 1;

在primary查询中用到的表t为system。

②、const:仅仅能查到一条数据的SQL,用于Primay key或者unique索引(与索引类型有关)

在存在主键索引的前提下执行:
    explain select tid from test1 where tid = 1;

删除主键索引,创建普通索引再次执行
    alter table test1 drop primary key ;
    create index test1_index on test1(tid);
explain select tid from test1 where tid = 1;

eq_ref唯一性索引,对于每个索引键的查询,返回匹配唯一行数据(有且只有1个,不能多、不能0)

即 通过索引列查出的数据,该索引列的数据唯一不能重复;常见于唯一索引和主键索引

测试:

将表数据恢复一下

给teacherCard的tcid设置主键约束,给teacher的tcid设置唯一约束。

alter table teacherCard add constraint pk_tcid primary key(tcid);
alter table teacher add constraint uk_tcid unique index(tcid);

explain select t.tcid from teacher t,teacherCard tc where t.tcid = tc.tcid ;

删除teacher后面的几条记录的原因是:如果不删除teacher表中tcid为4,5,6的三条数据是不会查出来的。这样不满足其不能为0的情况。

ref:非唯一性索引,对于每个索引键的查询,返回匹配的所有行(0,多)

测试:

增加数据

为tname增加索引

alter table teacher add index tname_index(tname);

explain select * from teacher where tname = 'tz';

小结:根据索引列查询

range:检索指定范围的行,where后面是一个范围查询(between,> < >=,特殊:in可能会时效,当查询的数据量大于一半的时候会转化为ALL)

index:查询全部索引中的数据

     explain select tid from teacher ; --tid 是索引, 只需要扫描索引表,不需要所有表中的所有数据

all:查询全部表中的数据

     explain select cid from course ;  --cid不是索引,需要全表所有,即需要所有表中的所有数据

 

4、possible_key分析

         预测可能用到的索引

 

5、key分析

         实际使用到的索引

6、key_len 分析

          索引的长度 

char-not null情况

创建一个表
create table test_kl
(
	name char(20) not null default ''
);

--为name设置一个index
alter table test_kl add index index_name(name) ;


--按刚才的索引查询
explain select * from test_kl where name ='' ; 

小结:utf8 1个字符占3个字节

char-null情况

alter table test_kl add column name1 char(20) ;  

alter table test_kl add index index_name1(name1) ;

explain select * from test_kl where name1 ='' ; 

小结:如果索引字段可以为null,会使用1个字节用于标识

增加一个复合索引

drop index index_name on test_kl ;
drop index index_name1 on test_kl ;

增加一个复合索引 
alter table test_kl add index name_name1_index (name,name1) ; 

explain select * from test_kl where name1 = '' ; --121(如果用到了name1,则一定用了name)
explain select * from test_kl where name = '' ; --60

使用varchar的情况:会再用2个额外的字节标识可变长度

7、ref分析

作用: 指明当前表所 参照的 字段。

执行如下语句:
    explain select * from course c,teacher t where c.tid = t.tid and t.tname = 'tw';
(注意要求c.tid t.tid t.tname为索引列)

小结:第一次查询参照的是tw这个常量,所以为const,第二次查询参照的是t.tid

8、rows分析

被索引优化查询的数据个数(实际通过索引而查询到的数据个数)

9、Extra分析

①、using filesort:性能消耗大;需要额外的一次排序(查询)。常见于order by中

构造表,并创建索引
create table test02
(
	a1 char(3),
	a2 char(3),
	a3 char(3),
	index idx_a1(a1),
	index idx_a2(a2),
	index idx_a3(a3)
);

分别执行如下语句
explain select * from test02 where a1 = '' order by a2;
explain select * from test02 where a1 = '' order by a3;
explain select * from test02 where a2 = '' order by a1;
explain select * from test02 where a2 = '' order by a3;
explain select * from test02 where a3 = '' order by a1;
explain select * from test02 where a3 = '' order by a2;
都会出现filesort

执行
explain select * from test02 where a1 = '' order by a1;
explain select * from test02 where a2 = '' order by a2;
explain select * from test02 where a3 = '' order by a3;
则不会出现

小结:单索引情况下:查询和排序使用相同的索引不会出现filesort,查询和排序使用不同的索引会出现filesort。因为使用不同的索引列会重新进行一次排序。

创建表,创建复合索引
drop index idx_a1 on test02;
drop index idx_a2 on test02;
drop index idx_a3 on test02;

创建复合索引
alter table test02 add index idx_a1_a2_a3 (a1,a2,a3) ;

执行如下语句
explain select *from test02 where a1='' order by a3 ;  --using filesort
explain select *from test02 where a2='' order by a3 ; --using filesort
explain select *from test02 where a1='' order by a2 ;
explain select *from test02 where a2='' order by a1 ; --using filesort

小结:复合索引情况下:只要跨列或无序使用都会出现filesort

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值