首页 > 数据库 > 国内数据库 > 达梦执行计划-操作符之多表连接
多表连接的三种方式:
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/ ,如需转载,请注明出处,否则将追究法律责任。