子查詢包含where ..or在Corelated Subquery 中語句中問題
我們知道語句中where... or.....可能對執行計劃造成的錯誤。現在我們看一下
corelated subquery 可能造成的SQL的執行計劃的問題。
1、測試:
備註,本測試載入資料的多少不會對執行計劃造成影響
create table t1
(
id NUMBER(13) not null,
rpadding VARCHAR2(13)
);
insert into t1 values(0,100);
insert into t1 values(0,100);
insert into t1 values(0,100);
commit;
create table t2
(
id number ,
small_vc NUMBER(15)
);
insert into t2 values(1,100);
insert into t2 values(2,100);
insert into t2 values(1,100);
insert into t2 values(1,100);
commit;
2、檢視執行計劃
set autotrace traceonly explain
select a.rowid ri,
a.*
from t2 a
where a.id=1
AND a.small_vc IS NOT NULL
AND NOT EXISTS
(SELECT 1 FROM t1
WHERE (rpadding = a.small_vc ) or ( id = a.small_vc )
)
-------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2 | 76 | 5 (0) | 00:00:01 |
|* 1 | FILTER | | | | | |
|* 2 | TABLE ACCESS FULL | T2 | 3 | 114 | 2 (0)| 00:00:01 |
|* 3 | TABLE ACCESS FULL | T1 | 1 | 21 | 2 (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------------------
我們看到執行計劃為filter。通常子查詢採用"no_unnest " hint的時候,執行計劃
為filter,但預設為unnest。為了避免可能影響,我們在子查詢中加入unnest,但
執行計劃未變。
如果子查詢條件將where ....or改成where.... and,執行計劃正常
-----------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 59 | 5 (20)| 00:00:01 |
|* 1 | HASH JOIN ANTI | | 1 | 59 | 5 (20)| 00:00:01 |
|* 2 | TABLE ACCESS FULL | T2 | 3 | 114 | 2 (0)| 00:00:01 |
| 3 | TABLE ACCESS FULL | T1 | 3 | 63 | 2 (0)| 00:00:01 |
------------------------------------------------------------------------------------------------------------
目前對該問題的解決辦法暫時只能重寫語句
(where a or b) <=> (where a and b)
select a.rowid ri,
a.*
from t2 a
where a.id=1
AND a.small_vc IS NOT NULL
AND NOT EXISTS
(SELECT 1 FROM t1
WHERE rpadding = a.small_vc
)
and NOT EXISTS
(SELECT 1 FROM t1
WHERE id = a.small_vc
)
----------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 59 | 7 (15)| 00:00:01 |
|* 1 | HASH JOIN ANTI | | 1 | 59 | 7 (15)| 00:00:01 |
|* 2 | HASH JOIN ANTI | | 1 | 51 | 5 (20)| 00:00:01 |
|* 3 | TABLE ACCESS FULL | T2 | 3 | 114 | 2 (0)| 00:00:01 |
| 4 | TABLE ACCESS FULL | T1 | 3 | 39 | 2 (0)| 00:00:01 |
| 5 | TABLE ACCESS FULL | T1 | 3 | 24 | 2 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------------------
corelated subquery 可能造成的SQL的執行計劃的問題。
1、測試:
備註,本測試載入資料的多少不會對執行計劃造成影響
create table t1
(
id NUMBER(13) not null,
rpadding VARCHAR2(13)
);
insert into t1 values(0,100);
insert into t1 values(0,100);
insert into t1 values(0,100);
commit;
create table t2
(
id number ,
small_vc NUMBER(15)
);
insert into t2 values(1,100);
insert into t2 values(2,100);
insert into t2 values(1,100);
insert into t2 values(1,100);
commit;
2、檢視執行計劃
set autotrace traceonly explain
select a.rowid ri,
a.*
from t2 a
where a.id=1
AND a.small_vc IS NOT NULL
AND NOT EXISTS
(SELECT 1 FROM t1
WHERE (rpadding = a.small_vc ) or ( id = a.small_vc )
)
-------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2 | 76 | 5 (0) | 00:00:01 |
|* 1 | FILTER | | | | | |
|* 2 | TABLE ACCESS FULL | T2 | 3 | 114 | 2 (0)| 00:00:01 |
|* 3 | TABLE ACCESS FULL | T1 | 1 | 21 | 2 (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------------------
我們看到執行計劃為filter。通常子查詢採用"no_unnest " hint的時候,執行計劃
為filter,但預設為unnest。為了避免可能影響,我們在子查詢中加入unnest,但
執行計劃未變。
如果子查詢條件將where ....or改成where.... and,執行計劃正常
-----------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 59 | 5 (20)| 00:00:01 |
|* 1 | HASH JOIN ANTI | | 1 | 59 | 5 (20)| 00:00:01 |
|* 2 | TABLE ACCESS FULL | T2 | 3 | 114 | 2 (0)| 00:00:01 |
| 3 | TABLE ACCESS FULL | T1 | 3 | 63 | 2 (0)| 00:00:01 |
------------------------------------------------------------------------------------------------------------
目前對該問題的解決辦法暫時只能重寫語句
(where a or b) <=> (where a and b)
select a.rowid ri,
a.*
from t2 a
where a.id=1
AND a.small_vc IS NOT NULL
AND NOT EXISTS
(SELECT 1 FROM t1
WHERE rpadding = a.small_vc
)
and NOT EXISTS
(SELECT 1 FROM t1
WHERE id = a.small_vc
)
----------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 59 | 7 (15)| 00:00:01 |
|* 1 | HASH JOIN ANTI | | 1 | 59 | 7 (15)| 00:00:01 |
|* 2 | HASH JOIN ANTI | | 1 | 51 | 5 (20)| 00:00:01 |
|* 3 | TABLE ACCESS FULL | T2 | 3 | 114 | 2 (0)| 00:00:01 |
| 4 | TABLE ACCESS FULL | T1 | 3 | 39 | 2 (0)| 00:00:01 |
| 5 | TABLE ACCESS FULL | T1 | 3 | 24 | 2 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------------------
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/354732/viewspace-732358/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- GORM subquery 子查詢GoORM
- 什麼是SQL 語句中相關子查詢與非相關子查詢SQL
- MySQL UDF 在 in ( subquery where ) bugMySql
- Mysql中的巢狀子查詢問題QSBSMySql巢狀
- sql語句中where一定要放在group by 之前SQL
- Python 提取出SQL語句中Where的值的方法PythonSQL
- Oracle 查詢轉換-04 Subquery UnnestingOracle
- Laravel 的 where or 查詢Laravel
- NOT IN之後的子查詢不能包含NULL值Null
- PostgreSQL 原始碼解讀(74)- 查詢語句#59(Review - subquery_...SQL原始碼View
- mysql 的delete from where 子查詢的一些限制MySqldelete
- thinkphp6----where查詢PHP
- SQL中 where 子句和having子句中的區別SQL
- SQL語句中 left join 後用 on 還是 where,區別大SQL
- Laravel 子查詢語句用法Laravel
- SQL語句中的AND和OR執行順序問題SQL
- 優化-mysql子查詢索引失效問題解決優化MySql索引
- SQL語言基礎(子查詢)SQL
- verilog中always塊語句中的暫存器變數自加問題變數
- MySQL 優化五(關聯查詢子查詢以及 in 的效率問題)(高階篇)MySql優化
- Oracle分組查詢中包含子查詢列,發生ORA-00937:不是單分組函式的錯誤Oracle函式
- 在Python中捕獲finally語句中異常訊息Python
- 關於 mysql 中的 rand () 查詢問題MySql
- sql 模糊查詢問題SQL
- 複雜查詢—子查詢
- PostgreSQL 原始碼解讀(29)- 查詢語句#14(查詢優化-上拉子查詢)SQL原始碼優化
- 阿里面試題: (a,b,c)組合索引, 查詢語句select...from...where a=.. and c=..走索引嗎?阿里面試題索引
- 備忘:laravel 對查詢結果集可以迴圈where查詢Laravel
- leetcode題解(查詢表問題)LeetCode
- Laravel 中 sql 查詢 使用 group by 報錯問題。LaravelSQL
- SQL查詢的:子查詢和多表查詢SQL
- 在 with 查詢中只查詢個別欄位
- 第三章:查詢與排序(下)----------- 3.29 題解:判斷陣列的包含問題排序陣列
- MyBatis在SQL語句中取list的大小MyBatisSQL
- [20180928]避免表示式在sql語句中.txtSQL
- sphinx查詢過濾問題
- Laravel5.7 查詢問題Laravel
- python怎麼查詢字串中是否包含某個字串Python字串
- MySQL子查詢MySql