mysql 优化器链接消除笔记

1. 嵌套链接消除

连接存在多个层次,用括号标识连接的优先次序。嵌套连接消除,就是消除嵌套的连接层次,把多个层次的连接减少为较少层次的连接,尽量“扁平化”。

2. 链接消除

create table b(b1 int, b2 varchar(2), primary key(b1));

create table a(a1 int, a2 varchar(2), foreign key(a1) references b(b1));

create table c(c1 int, c2 varchar(2));

insert into b values(1, 'b1');

insert into b values(2, 'b2');

insert into b values(3, 'b3');

insert into a values(1, 'a1');

insert into a values(null, 'a2');

insert into a values(3, 'a3');

insert into c values(1, 'c1');

insert into c values(2, 'c2');

insert into c values(null, 'c3');

①情况一(MySQL不支持)

唯一键/主键作为连接条件,三表内连接可以去掉中间表(中间表的列只作为连接条件)。

如:

t1(t1_c1 int unique, t1_c2 int);

t2(t2_c1 int unique, t2_c2 int);

t3(t3_c1 int unique, t3_c2 int);

select t1.*, t3.* from t1,t2,t3 where t1.t1_c1 = t2.t2_c1 and t2.t2_c1 = t3.t3_c1;

可以消除t2表转为

select t1.*, t3.* from t1,t3 where t1.t1_c1 = t3.t3_c1;

②情况二(MySQL不支持)

一些特殊形式,可以消除连接操作(可消除的表除了作为连接对象外,不出现在任何子句中)。

select max(a1) from a,b;

③情况三(MySQL不支持)

主外键关系的表进行的连接,可消除主键表,这不会影响对外键表的查询。目标主键只作为连接对象和连接条件存在。

对主外键参照的表进行内连接,可以消除主键表(b)

1)

explain extended select a.*, c.* from a,b,c where a.a1=b.b1 and b.b1 = c.c1;

2)

explain extended select a.*, c.* from a,c where a.a1= c.c1 and a.a1 is not null;

3)

explain extended select a.*, c.* from a,c where a.a1= c.c1;

A->B : A表依赖B表,这里如果ABC内连接,结果无B表的列出现,仅仅作为连接条件。

b.b1最为“桥“,且b.b1肯定不为空(null)。

sql1 中的连接条件a.a1=b.b1 and b.b1 = c.c1; a.a1可能为null,但是不满足a.a1=b.b1,因为b.b1不为空,所以对已这类记录可以过滤。

a.a1 is not null 可保证1)和2)等价。

对主外键参照的表进行外连接,可以消除主键表

select a.*, c.* from a left join b on(a1=b1) join c on (a1 = c1);

同样b.b1作为桥,可以消除。

select a.*,c.* from a left join c on(a1 =c1);

注: 如果a1列不为null,则肯定等价:

        如果a1列为null,a1=b1 -> false

                                  a1=c1 -> false

所以也等价。

你可能感兴趣的:(mysql 优化器链接消除笔记)