欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

对表的连接的总结

程序员文章站 2022-07-01 10:01:46
1.嵌套循环访问的次数SYS@ PROD>create table t1( id number not null, n number, contents varchar2(4000) );SYS@ PROD>create table t2( id number not null, t1_id num ......

1.嵌套循环访问的次数
SYS@ PROD>create table t1(
id number not null,
n number,
contents varchar2(4000)
);
SYS@ PROD>create table t2(
id number not null,
t1_id number not null,
n number,
contents varchar2(4000)
);
SYS@ PROD>execute dbms_random.seed(0);

SYS@ PROD>insert into t1
select rownum,rownum,dbms_random.string('a',50)
from dual
connect by level<=100
order by dbms_random.random;
SYS@ PROD>insert into t2 select rownum,rownum,rownum,dbms_random.string('b',50) from dualconnect by level<=100000 order by dbms_random.random;
SYS@ PROD>commit;
SYS@ PROD>select count(*) from t1;100
SYS@ PROD>select count(*) from t2;100000
测试:
set linesize 1000
alter session set ststistics_level=all;
select /*+leading(t1) user_nl(t2)*/* from t1,t2 where t1.id=t2.t1_id;
select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));
发现执行计划里面Starts列t1表访问1次,t2表访问100次
1>SYS@ PROD>select /*+leading(t1) use_nl(t2)*/*
from t1,t2
where t1.id=t2.t1_id
and t1.n in(17,19);
SYS@ PROD>select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));
发现执行计划里面Starts列t1表访问1次,t2表访问2次
2>SYS@ PROD>select /*+leading(t1) use_nl(t2)*/*
from t1,t2
where t1.id=t2.t1_id
and t1.n=19;
发现执行计划里面Starts列t1表访问1次,t2表访问1次
3>SYS@ PROD>select /*+leading(t1) use_nl(t2)*/*
from t1,t2
where t1.id=t2.t1_id
and t1.n=999999999;
发现执行计划里面Starts列t1表访问1次,t2表访问0次
结论:t1表的查询返回多少条记录,t2表就访问多少次。

HINT的含义,其中use_nl表示强制用嵌套循环的方式连接,leading(t1)表示强制先访问t1表,也就是t1表作为驱动表,增加这些HINT
提示的目的只是为了确保我们的SQL语句的执行计划在做嵌套循环连接。在嵌套循环连接中,驱动表返回多少条记录,被驱动表就访问多少次。
2.哈希连接表的访问次数
/*leading(*) use_hash(t2)*/*
结论:在HASH连接中,驱动表和被驱动表都只会访问0次或者1次。
3.排序合并的访问次数
/*leading(*) use_merge(t2)*/*
结论:排序合并连接根本就没有驱动和被驱动的概念,而嵌套循环和哈希连接要考虑驱动和被驱动情况。

三种访问顺序的比较:
1.嵌套循环连接特别要注意驱动表的顺序,小的结果集先访问,大的结果集后访问,才能保证被驱动表的访问次数降到最低,从而提升性能。
2.哈希循环顺序也重要
3.嵌套循环连接和哈希连接有驱动顺序,驱动表的顺序不同将影响连接的性能,而排序合并连接没有驱动的概念,无论哪张表都无妨。
三种访问的排序:
嵌套和哈希不需要排序,而排序合并需要排序。

适合连接条件范围的比较:
1.HASH连接查询条件不支持<>,大于和小于的写法,也不支持like的连接方式,如果加了这些连接条件,会走全表扫描。
2.排序合并连接不支持<>,也不支持like的连接条件,但支持>和<之类的连接条件。遇到
3.嵌套循环支持所有的sql连接条件的写法,没有任何限制。

最适合NL连接的场景
①两表关联返回的记录不多,最佳情况是驱动表结果集仅返回1条,或少量几条记录,而被驱动表仅匹配到1条或少量几条数据
这种情况即便t1表和t2表的记录奇大无比,也是非常迅速的。
②遇到一些不等值查询导致哈希和排序合并连接被限制使用,不得不使用NL连接。

排序合并连接上的连接条件虽然没有检索功能却有消除排序的作用。