Anti-Join中允許關聯column為空值( null),造成hint失效
”Join型別名詞"中介紹Anti-Join主要是Not in或Not exists格式,以下實驗是驗證關聯column允許空值(null)的時候,可能造成hint不能生效。
具體實驗步驟如下:
1、建立EMP和DEPT表,其中dept_no允許空值
SQL>create table emp (
dept_no number,
sal number,
emp_no number,
padding varchar2(60),
constraint e_pk primary key(emp_no)
);
SQL>create table dept (
dept_no number(6),
dept_group number
);
2、插入資料
SQL>insert into emp
select
mod(rownum,6),
rownum,
rownum,
rpad('x',60)
from
all_objects
where
rownum <= 20000;
SQL>insert into dept values(0, 1);
insert into dept values(1, 1);
insert into dept values(2, 1);
insert into dept values(3, 2);
insert into dept values(4, 2);
insert into dept values(5, 2);
SQL>commit;
3、統計分析(略)
4、檢視預設執行計劃
SQL>set autotrace traceonly explain
SQL>select
emp.*
from
emp
where
emp.dept_no not in (
select
dept.dept_no
from dept
where dept.dept_group = 2
);
執行計劃1:
--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 16667 | 1171K| 34 |
|* 1 | FILTER | | | | |
| 2 | TABLE ACCESS FULL | EMP | 20000 | 1406K | 22 |
|* 3 | TABLE ACCESS FULL | DEPT | 1 | 5 | 2 |
--------------------------------------------------------------------------------------
5、無論在語句中新增如nl_aj,merge_aj,hash_aj等hint,所有hint都不能生效,執行計劃不變,與執行計劃1一樣。
SQL>select
emp.*
from
emp
where
emp.dept_no not in (
select /*+ hash_aj */
dept.dept_no
from dept
where dept.dept_group = 2
);
6、對錶EMP和DEPT中的dept_no增加非空約束。
SQL>alter table dept modify dept_no not null;
SQL>alter table emp modify dept_no not null;
7、重新執行上述失效語句,hint生效
--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 3333 | 250K| 25 |
|* 1 | HASH JOIN RIGHT ANTI | | 3333 | 250K| 25 |
|* 2 | TABLE ACCESS FULL | DEPT | 6 | 30 | 2 |
| 3 | TABLE ACCESS FULL | EMP | 20000 | 1406K| 22 |
---------------------------------------------------------------------------------------
8、或者在語句中新增dept_no is not null,使得hint生效,執行計劃如執行計劃2
SQL>alter table dept modify dept_no null;
SQL>alter table emp modify dept_no null;
SQL>select
emp.*
from
emp
where
emp.dept_no in (
select /*+ hash_sj */
dept.dept_no
from dept
where dept.dept_group = 1
and dept.dept_no is not null
)
and emp.dept_no is not null;
注:實驗素材來自於Jonathan Lewis
具體實驗步驟如下:
1、建立EMP和DEPT表,其中dept_no允許空值
SQL>create table emp (
dept_no number,
sal number,
emp_no number,
padding varchar2(60),
constraint e_pk primary key(emp_no)
);
SQL>create table dept (
dept_no number(6),
dept_group number
);
2、插入資料
SQL>insert into emp
select
mod(rownum,6),
rownum,
rownum,
rpad('x',60)
from
all_objects
where
rownum <= 20000;
SQL>insert into dept values(0, 1);
insert into dept values(1, 1);
insert into dept values(2, 1);
insert into dept values(3, 2);
insert into dept values(4, 2);
insert into dept values(5, 2);
SQL>commit;
3、統計分析(略)
4、檢視預設執行計劃
SQL>set autotrace traceonly explain
SQL>select
emp.*
from
emp
where
emp.dept_no not in (
select
dept.dept_no
from dept
where dept.dept_group = 2
);
執行計劃1:
--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 16667 | 1171K| 34 |
|* 1 | FILTER | | | | |
| 2 | TABLE ACCESS FULL | EMP | 20000 | 1406K | 22 |
|* 3 | TABLE ACCESS FULL | DEPT | 1 | 5 | 2 |
--------------------------------------------------------------------------------------
5、無論在語句中新增如nl_aj,merge_aj,hash_aj等hint,所有hint都不能生效,執行計劃不變,與執行計劃1一樣。
SQL>select
emp.*
from
emp
where
emp.dept_no not in (
select /*+ hash_aj */
dept.dept_no
from dept
where dept.dept_group = 2
);
6、對錶EMP和DEPT中的dept_no增加非空約束。
SQL>alter table dept modify dept_no not null;
SQL>alter table emp modify dept_no not null;
7、重新執行上述失效語句,hint生效
--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 3333 | 250K| 25 |
|* 1 | HASH JOIN RIGHT ANTI | | 3333 | 250K| 25 |
|* 2 | TABLE ACCESS FULL | DEPT | 6 | 30 | 2 |
| 3 | TABLE ACCESS FULL | EMP | 20000 | 1406K| 22 |
---------------------------------------------------------------------------------------
8、或者在語句中新增dept_no is not null,使得hint生效,執行計劃如執行計劃2
SQL>alter table dept modify dept_no null;
SQL>alter table emp modify dept_no null;
SQL>select
emp.*
from
emp
where
emp.dept_no in (
select /*+ hash_sj */
dept.dept_no
from dept
where dept.dept_group = 1
and dept.dept_no is not null
)
and emp.dept_no is not null;
注:實驗素材來自於Jonathan Lewis
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/354732/viewspace-622131/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- null(空值)小結Null
- SQL中的空值NULLSQLNull
- Transformation之NUll-aware Anti-join(NAAJ)【九】ORMNull
- mysql 空值(null)和空字元('')的區別MySqlNull字元
- 一對多關聯表,怎麼判斷返回關聯陣列不為空的值啊?陣列
- 資料庫系統 空值 null資料庫Null
- mysql中null與“空值”的坑MySqlNull
- MySQL裡null與空值的辨析MySqlNull
- Ubuntu中允許root遠端ssh登入的方法Ubuntu
- mssql sqlserver in 關鍵字在值為null的應用舉例SQLServerNull
- 關於null值的小知識Null
- 索引失效系列——說說is null索引Null
- oracle group by與分組列為null空OracleNull
- 為什麼hashtable不允許設定Null但是hashmap允許?NullHashMap
- 【NULL】Oracle null值介紹NullOracle
- ROUND(x,y)與TRUNC(x,y)函式中y引數值為省略、空值與null的區別函式Null
- C#可空型別,int可以為nullC#型別Null
- Java判斷欄位是否為空,為空賦值 ?Java賦值
- 判斷物件值是否為空物件
- Spark2 Dataset DataFrame空值null,NaN判斷和處理SparkNullNaN
- NULL 值與索引Null索引
- 關於NULL值在索引裡的兩個疑惑Null索引
- 不再迷惑,無值和 NULL 值Null
- In V$SESSION, column SQL_ID is not NULL while STATUS is INACTIVESessionSQLNullWhile
- duplicate ORA-01405: fetched column value is NULLNull
- 為什麼HashMap的鍵值可以為null,而ConcurrentHashMap不行?HashMapNull
- php給$_POST賦值會導致值為空PHP賦值
- MySQL null值儲存,null效能影響MySqlNull
- Oracle-空值null和數字相加的問題-nvl函式OracleNull函式
- 將一個物件裡所有的空值屬性設定成null物件Null
- sqlserver、oracle資料庫排序空值null問題解決辦法SQLServerOracle資料庫排序Null
- <a>為空使用href屬性值填充
- cursor_sharing=force導致sql profile部分hint失效SQL
- 關於ORACLE MYSQL NOT IN和NOT exists需要注意的 NULL值OracleMySqlNull
- NULL 值與索引(二)Null索引
- hive中的null值HiveNull
- hive NULL值影響HiveNull
- case when遇上null值Null