ITPub博客

首页 > 数据库 > 国内数据库 > 达梦执行计划-操作符之多表连接

达梦执行计划-操作符之多表连接

原创 国内数据库 作者:yanhengdoudou 时间:2020-03-27 11:16:20 0 删除 编辑

多表连接的三种方式:

HASH JOIN  (哈希连接)

MERGE JOIN (归并连接,也叫排序归并连接)

NESTED LOOP (嵌套循环连接)

 

Hash join的工作方式是将一个表(通常是小一点的那个表)做hash运算,将列数据存储到hash列表中,从另一个表中抽取记录,做hash运算,到hash 列表中找到相应的值,做匹配。

 

Nested loops 工作方式是从一张表中读取数据,访问另一张表(通常是索引)来做匹配,nested loops适用的场合是当一个关联表比较小的时候,效率会更高。

 

Merge Join 是先将关联表的关联列各自做排序,然后从各自的排序表中抽取数据,到另一个排序表中做匹配,因为merge join需要做更多的排序,所以消耗的资源更多

 

一般来说:

等值连接条件一般会选择哈希连接;

非等值连接条件会采用嵌套连接;

连接列均为索引列时,会采用归并连接。

 

模拟操作符:

创建实验表:

create table tab1(c1 int,c2 int ,c3 int);

create table tab2(c1 int,c2 int ,c3 int);

insert into tab1 select level,level,level from DUAL CONNECT by level <100000;

insert into tab2 select level,level,level from DUAL CONNECT by level <100000;

create index ind_tab1 on tab1(c1);

create index ind_tab2 on tab2(c1);

select * from user_indexes where table_name in ('TAB1','TAB2')

 

1.HASH2 INNER JOIN

操作符模拟:(HASH内连接)

select tab1.c1,tab2.c2 from tab1 , tab2 where tab1.c1=tab2.c1

1   #NSET2: [41, 98901000, 12] 

2     #PRJT2: [41, 98901000, 12]; exp_num(2), is_atom(FALSE) 

3       #HASH2 INNER JOIN: [41, 98901000, 12];  KEY_NUM(1);

4         #SSCN: [10, 99999, 4]; IND_TAB1(TAB1)

5         #CSCN2: [10, 99999, 8]; INDEX33555736(TAB2)

select tab1.c1,tab2.c2 from tab1 join tab2 on tab1.c1=tab2.c1

1   #NSET2: [41, 98901000, 12] 

2     #PRJT2: [41, 98901000, 12]; exp_num(2), is_atom(FALSE) 

3       #HASH2 INNER JOIN: [41, 98901000, 12];  KEY_NUM(1);

4         #SSCN: [10, 99999, 4]; IND_TAB1(TAB1)

5         #CSCN2: [10, 99999, 8]; INDEX33555736(TAB2)

 

2.MERGE INNER JOIN3

模拟:(归并内连接)连接列有索引且只需要返回索引列归并更合适

select tab1.c1 from tab1 , tab2 where tab1.c1=tab2.c1

 

1   #NSET2: [40, 99800099, 8] 

2     #PRJT2: [40, 99800099, 8]; exp_num(1), is_atom(FALSE) 

3       #MERGE INNER JOIN3: [40, 99800099, 8]; 

4         #SSCN: [10, 99999, 4]; IND_TAB1(TAB1)

5         #SSCN: [10, 99999, 4]; IND_TAB2(TAB2)

 

select tab1.c1 from tab1 join tab2 on tab1.c1=tab2.c1

1   #NSET2: [40, 99800099, 8] 

2     #PRJT2: [40, 99800099, 8]; exp_num(1), is_atom(FALSE) 

3       #MERGE INNER JOIN3: [40, 99800099, 8]; 

4         #SSCN: [10, 99999, 4]; IND_TAB1(TAB1)

5         #SSCN: [10, 99999, 4]; IND_TAB2(TAB2)

 

3.HASH LEFT JOIN2

模拟:(HASH左外连接)

select tab1.c1 from tab1 left  join tab2 on tab1.c1=tab2.c1

1   #NSET2: [41, 98901000, 4] 

2     #PRJT2: [41, 98901000, 4]; exp_num(1), is_atom(FALSE) 

3       #HASH LEFT JOIN2: [41, 98901000, 4]; key_num(1), partition_keys_num(0)

4         #SSCN: [10, 99999, 4]; IND_TAB1(TAB1)

5         #SSCN: [10, 99999, 4]; IND_TAB2(TAB2)

 

4.HASH FULL JOIN2

模拟:(HASH 全外连接)

select tab2.c1 from tab1 full outer join tab2 on tab2.c1=tab1.c1 

1   #NSET2: [41, 98901000, 4] 

2     #PRJT2: [41, 98901000, 4]; exp_num(1), is_atom(FALSE) 

3       #HASH FULL JOIN2: [41, 98901000, 4]; key_num(1), 

4         #SSCN: [10, 99999, 4]; IND_TAB1(TAB1)

5         #SSCN: [10, 99999, 4]; IND_TAB2(TAB2)

 

5.HASH LEFT SEMI MULTIPLE JOIN

模拟:(多列not in)

select * from tab1 where (c1,c2) not in (select c1,c2 from tab2)

1   #NSET2: [43, 99749, 20] 

2     #PRJT2: [43, 99749, 20]; exp_num(4), is_atom(FALSE) 

3       #HASH LEFT SEMI MULTIPLE JOIN: [43, 99749, 20];  (ANTI), join condition((exp11 AND exp11))

4         #CSCN2: [10, 99999, 20]; INDEX33555735(TAB1)

5         #PRJT2: [10, 99999, 8]; exp_num(2), is_atom(FALSE) 

6           #CSCN2: [10, 99999, 8]; INDEX33555736(TAB2)

6.HASH RIGHT JOIN2

模拟:(HASH右外连接)

select t.c1 ,tab1.c3 from tab1 left join (select * from tab2 where c1=10)t on t.c1=tab1.c2 

1   #NSET2: [20, 99999, 20] 

2     #PRJT2: [20, 99999, 20]; exp_num(2), is_atom(FALSE) 

3       #HASH RIGHT JOIN2: [20, 99999, 20]; key_num(1), 

4         #PRJT2: [2, 2499, 12]; exp_num(1), is_atom(FALSE) 

5           #SSEK2: [2, 2499, 12]; scan_type(ASC), IND_TAB2(TAB2), scan_range[10,10]

6         #CSCN2: [10, 99999, 8]; INDEX33555735(TAB1)

7.HASH LEFT SEMI JOIN2

模拟:(哈希半连接)子查询和非等值连接出现

select * from tab1 where c1 not in (select c1 from tab2)

1   #NSET2: [42, 1, 20]

2     #PRJT2: [42, 1, 20]; exp_num(4), is_atom(FALSE)

3       #HASH LEFT SEMI JOIN2: [42, 1, 20];  (ANTI),KEY_NUM(1);

4         #CSCN2: [10, 99999, 20]; INDEX33555735(TAB1)

5         #SSCN: [10, 99999, 4]; IND_TAB2(TAB2)

8.NEST LOOP INDEX JOIN2

模拟:(索引内连接)

select tab1.c1 from tab1 ,tab2 where tab1.c1>tab2.c1

1   #NSET2: [15758, 374896251, 8] 

2     #PRJT2: [15758, 374896251, 8]; exp_num(1), is_atom(FALSE) 

3       #NEST LOOP INDEX JOIN2: [15758, 374896251, 8] 

4         #SSCN: [10, 99999, 4]; IND_TAB1(TAB1)

5         #SSEK2: [5249, 3749, 0]; scan_type(ASC), IND_TAB2(TAB2), scan_range(null2,TAB1.C1)

 

9.NEST LOOP INNER JOIN2

模拟:(嵌套循环内连接)

select tab1.c1 from tab1 ,tab2 where tab1.c2>tab2.c2

1   #NSET2: [834902606588, 499990000, 12] 

2     #PRJT2: [834902606588, 499990000, 12]; exp_num(1), is_atom(FALSE) 

3       #SLCT2: [834902606588, 499990000, 12]; TAB1.C2 > TAB2.C2

4         #NEST LOOP INNER JOIN2: [834902606588, 499990000, 12]; 

5           #CSCN2: [10, 99999, 8]; INDEX33555735(TAB1)

6           #CSCN2: [10, 99999, 4]; INDEX33555736(TAB2)

10.NEST LOOP LEFT JOIN2

模拟:(嵌套循环左连接)

select tab1.c1 from tab1 left join tab2 on tab1.c2>tab2.c2

1   #NSET2: [830882917248, 499990000, 8] 

2     #PRJT2: [830882917248, 499990000, 8]; exp_num(1), is_atom(FALSE) 

3       #NEST LOOP LEFT JOIN2: [830882917248, 499990000, 8]; join condition(TAB1.C2 > TAB2.C2) partition_keys_num(0)

4         #CSCN2: [10, 99999, 8]; INDEX33555735(TAB1)

5         #CSCN2: [10, 99999, 4]; INDEX33555736(TAB2)

 

 

 


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69949798/viewspace-2679240/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2019-09-29

  • 博文量
    70
  • 访问量
    193340