關於oracle中的半連線(r3筆記55天)
阿新 • • 發佈:2022-05-04
表的連線在sql語句中尤為重要。外連線,內連線,半連線,反連線等等各種連線,看似簡單的一個連線裡面還是有不少的細節的。對於sql調優來說也是很重要的。 像下面的形式的sql就屬於半連線,使用了in子句,對於exists的實現也是屬於半連線。
--in半連線 SQL> select dname from dept dept where deptno in (select deptno from emp emp); DNAME -------------- RESEARCH SALES ACCOUNTING --exists半連線 SQL> select dname from dept dept where exists (select null from emp emp where emp.deptno=dept.deptno) 2 / DNAME -------------- RESEARCH SALES ACCOUNTING
可能對於上面兩種連線大家不以為然,認為把需要用到的表直接放在from子句後效果是一致的,答案也不是肯定的。 比如下面的形式,可能輸出的結果就多了很多。大概14條記錄,但是通過半連線的方式會輸出3行記錄。
SQL> select dept.dname from dept dept,emp empwhere dept.deptno=emp.deptno; DNAME -------------- RESEARCH SALES SALES RESEARCH SALES SALES ACCOUNTING RESEARCH ACCOUNTING SALES RESEARCH SALES RESEARCH ACCOUNTING 14 rows selected.
所以說如果要得到一個相同的輸出結果,還是需要distinct+inner join
SQL> select distinct dept.dname from dept dept,emp emp where dept.deptno=emp.deptno;
DNAME
--------------
ACCOUNTING
RESEARCH
SALES
對於半連線的可替換實現,大體有以下幾種方式
--使用集合 select dept.dname from dept dept, (select deptno from dept intersect select deptno from emp emp)b where dept.deptno=b.deptno ; DNAME -------------- ACCOUNTING RESEARCH SALES --使用any SQL> select dept.dname from dept dept where deptno=any(select deptno from emp emp); DNAME -------------- RESEARCH SALES ACCOUNTING --使用distinct和內連線 SQL> select distinct emp.deptno from dept dept,emp emp where dept.deptno=emp.deptno; DEPTNO ---------- 30 20 10 SQL> select distinct dept.deptno from dept dept,emp emp where dept.deptno=emp.deptno; DEPTNO ---------- 30 20 10
大體說了下關於半連線的一些實現,可能在實際的使用中,最直觀的感受還是通過執行計劃來看到。 啟用了半連線,在執行計劃中會有semi的字樣。
也可以手動指定不需要走半連線。使用Hint no_semijoin