11g優化器增加Null aware anti join
在前面的篇章中介紹了10g升級到11g,優化器增加了Null aware anti join功
能,具體針對這個功能我們進行如下的測試:
1、建立測試表
SQL>create table emp (
dept_no number not null,
sal number,
emp_no number,
padding varchar2(60),
constraint e_pk primary key(emp_no)
);
SQL>insert into emp select
mod(rownum,6),
rownum,
rownum,
rpad('x',60)
from all_objects
where rownum <= 20000;
SQL>create table dept (
dept_no number(6),
dept_group number
);
SQL>insert into dept values(0, 1);
SQL>insert into dept values(1, 1);
SQL>insert into dept values(2, 1);
SQL>insert into dept values(3, 2);
SQL>insert into dept values(4, 2);
SQL>insert into dept values(5, 2);
SQL>commit;
注意一點,我對dept_no沒有not null約束
2、統計分析(略)
3、10g的執行計劃如下
SQL>select emp.* from emp
where emp.dept_no in (
select dept.dept_no from dept
where dept.dept_group = 1);
執行計劃如下:
----------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU) | Time |
-----------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 8119 | 562K | 37 (0 )| 00:00:01 |
|* 1 | FILTER | | | | | |
| 2 | TABLE ACCESS FULL| EMP | 9743 | 675K | 25 (0 )| 00:00:01 |
|* 3 | TABLE ACCESS FULL| DEPT | 1 | 5 | 2 (0) | 00:00:01 |
----------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter( NOT EXISTS (SELECT /*+ */ 0 FROM "DEPT" "DEPT" WHERE
"DEPT"."DEPT_GROUP"=2 AND LNNVL("DEPT"."DEPT_NO"<>:B1)))
3 - filter("DEPT"."DEPT_GROUP"=2 AND LNNVL("DEPT"."DEPT_NO"<>:B1))
我們看到因為dept_no是nullable,所以呼叫了內部的function,其
selectivity(LNNVL)=5%,導致成本計算成本偏離了實際的值,具體成本計算方法、
分析和解決方法參看前面的文章《Anti-Join中允許關聯column為空值( null),造成
hint失效》。
4、11g版本中解決了anti-join column 空值問題,其執行計劃正常:
----------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU) | Time |
-----------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 6673 | 508K| 45 (3)| 00:00:01 |
|* 1 | HASH JOIN RIGHT ANTI NA| | 6673 | 508K| 45 (3)| 00:00:01 |
|* 2 | TABLE ACCESS FULL | DEPT | 3 | 18 | 2 (0)| 00:00:01 |
| 3 | TABLE ACCESS FULL | EMP | 13345 | 938K| 42 (0)| 00:00:01 |
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("EMP"."DEPT_NO"="DEPT"."DEPT_NO")
2 - filter("DEPT"."DEPT_GROUP"=2)
其是通過內部隱含引數_optimizer_null_aware_antijoin來控制,我們可以進行如下
測試:
alter session set "_optimizer_null_aware_antijoin"=false;
然後檢視SQL語句的執行計劃與步驟3 10g生成的執行計劃一致。
結論:在11g中,不用再考慮anti-join中column是否是空值了。
能,具體針對這個功能我們進行如下的測試:
1、建立測試表
SQL>create table emp (
dept_no number not null,
sal number,
emp_no number,
padding varchar2(60),
constraint e_pk primary key(emp_no)
);
SQL>insert into emp select
mod(rownum,6),
rownum,
rownum,
rpad('x',60)
from all_objects
where rownum <= 20000;
SQL>create table dept (
dept_no number(6),
dept_group number
);
SQL>insert into dept values(0, 1);
SQL>insert into dept values(1, 1);
SQL>insert into dept values(2, 1);
SQL>insert into dept values(3, 2);
SQL>insert into dept values(4, 2);
SQL>insert into dept values(5, 2);
SQL>commit;
注意一點,我對dept_no沒有not null約束
2、統計分析(略)
3、10g的執行計劃如下
SQL>select emp.* from emp
where emp.dept_no in (
select dept.dept_no from dept
where dept.dept_group = 1);
執行計劃如下:
----------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU) | Time |
-----------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 8119 | 562K | 37 (0 )| 00:00:01 |
|* 1 | FILTER | | | | | |
| 2 | TABLE ACCESS FULL| EMP | 9743 | 675K | 25 (0 )| 00:00:01 |
|* 3 | TABLE ACCESS FULL| DEPT | 1 | 5 | 2 (0) | 00:00:01 |
----------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter( NOT EXISTS (SELECT /*+ */ 0 FROM "DEPT" "DEPT" WHERE
"DEPT"."DEPT_GROUP"=2 AND LNNVL("DEPT"."DEPT_NO"<>:B1)))
3 - filter("DEPT"."DEPT_GROUP"=2 AND LNNVL("DEPT"."DEPT_NO"<>:B1))
我們看到因為dept_no是nullable,所以呼叫了內部的function,其
selectivity(LNNVL)=5%,導致成本計算成本偏離了實際的值,具體成本計算方法、
分析和解決方法參看前面的文章《Anti-Join中允許關聯column為空值( null),造成
hint失效》。
4、11g版本中解決了anti-join column 空值問題,其執行計劃正常:
----------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU) | Time |
-----------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 6673 | 508K| 45 (3)| 00:00:01 |
|* 1 | HASH JOIN RIGHT ANTI NA| | 6673 | 508K| 45 (3)| 00:00:01 |
|* 2 | TABLE ACCESS FULL | DEPT | 3 | 18 | 2 (0)| 00:00:01 |
| 3 | TABLE ACCESS FULL | EMP | 13345 | 938K| 42 (0)| 00:00:01 |
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("EMP"."DEPT_NO"="DEPT"."DEPT_NO")
2 - filter("DEPT"."DEPT_GROUP"=2)
其是通過內部隱含引數_optimizer_null_aware_antijoin來控制,我們可以進行如下
測試:
alter session set "_optimizer_null_aware_antijoin"=false;
然後檢視SQL語句的執行計劃與步驟3 10g生成的執行計劃一致。
結論:在11g中,不用再考慮anti-join中column是否是空值了。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/354732/viewspace-692564/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Transformation之NUll-aware Anti-join(NAAJ)【九】ORMNull
- Anti-Join中允許關聯column為空值( null),造成hint失效Null
- 【sql調優之執行計劃】merge semi join and merge anti joinSQL
- Oracle 11g中的_optimizer_null_aware_antijoin隱含引數OracleNull
- ZT:簡單介紹join,outer-join,semi-join,anti-join的區別
- join 查詢優化優化
- NOT IN、JOIN、IS NULL、NOT EXISTS效率對比Null
- 060611G _optimizer_null_aware_antijoinNull
- mysql left join 優化學習MySql優化
- 淺談查詢優化器中的JOIN演算法優化演算法
- in_list 11g優化器改進優化
- MySQL系列6 - join語句的優化MySql優化
- mysql update join優化update in查詢效率MySql優化
- 用LEFT JOIN優化標量子查詢優化
- 使用STRAIGHT_JOIN優化一則AI優化
- 對Hash Join的一次優化優化
- mysql的left join和inner join的效率對比,以及如何優化MySql優化
- 【Hive】資料傾斜優化 shuffle, join, group byHive優化
- 使用exists(Semi-Join)優化distinct語句優化
- Java通過Fork/Join來優化平行計算Java優化
- ORACLE SQL過濾條件是IS NULL or !=的優化OracleSQLNull優化
- 優化器優化
- 【MySQL】MySQL效能優化之Block Nested-Loop Join(BNL)MySql優化BloCOOP
- bitmap join index ---資料倉儲優化方法之一Index優化
- Oracle11gr2的PLSQL優化NULL語句OracleSQL優化Null
- Oracle優化案例-用left join代替反連線 not in not exists(十)Oracle優化
- 優化器提示優化
- oracle 11g增加業務profileOracle
- Oracle 11g 鎖特性增加Oracle
- Mysql資料庫的join演算法介紹,優美的執行優化MySql資料庫演算法優化
- JS日曆控制元件優化(增加時分秒)JS控制元件優化
- VuePress 部落格優化之增加 Vssue 評論功能Vue優化
- 增加複合索引優化SQL的簡單過程索引優化SQL
- oracle 的優化器Oracle優化
- 查詢優化器優化
- 【摘】 oracle優化器Oracle優化
- Oracle的優化器Oracle優化
- SQL 優先順序join>whereSQL