子查詢包含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
- Select from subquery 子查詢
- where語句中多條件查詢欄位NULL與NOT NULL不確定性查詢Null
- MySQL UDF 在 in ( subquery where ) bugMySql
- 什麼是SQL 語句中相關子查詢與非相關子查詢SQL
- 關於在SQL語句中ON和WHERE中條件使用的差異SQL
- Mysql中的巢狀子查詢問題QSBSMySql巢狀
- 查詢語句中escape的轉義字元字元
- CBO的查詢轉換(謂詞推入與子查詢展開(Subquery Unnesting))
- 在HQL select查詢語句中自定義查詢結果返回的資料型別資料型別
- No_expand hint 解決CBO針對where...or..語句中的cardinality計算問題
- hibhibernate中hql中的語句where語句查詢List出現空
- sql語句中where一定要放在group by 之前SQL
- SQL Server 2008 中SQL查詢語句中欄位值不區分大小寫問題處理SQLServer
- sql語句中較為重要的查詢邏輯SQL
- NOT IN之後的子查詢不能包含NULL值Null
- Laravel 的 where or 查詢Laravel
- PostgreSQL 原始碼解讀(74)- 查詢語句#59(Review - subquery_...SQL原始碼View
- 在 Sql語句中使用正規表示式來查詢你所要的字元SQL字元
- Transformation之Subquery Un-nesting(子查詢的非巢狀)SU【六】ORM巢狀
- sql語法相關子查詢與非相關子查詢SQL
- Oracle 查詢轉換-04 Subquery UnnestingOracle
- mysql 的delete from where 子查詢的一些限制MySqldelete
- SQL語句巢狀查詢問題SQL巢狀
- thinkphp6----where查詢PHP
- Python 提取出SQL語句中Where的值的方法PythonSQL
- Laravel 子查詢語句用法Laravel
- 模板中的名字查詢問題
- 子查詢-表子查詢
- SQL語句中 left join 後用 on 還是 where,區別大SQL
- MV定義語句中包含Fact的VIEW,能否Rewrite ?View
- 在關聯子查詢中in與exists的區別
- 優化-mysql子查詢索引失效問題解決優化MySql索引
- SQL語言基礎(子查詢)SQL
- SQL優化] 避免在WHERE子句中對列使用函式SQL優化函式
- SQL中 where 子句和having子句中的區別SQL
- SQL語句中的AND和OR執行順序問題SQL
- SQL查詢語句臃腫問題淺析SQL