將主查詢條件寫到子查詢裡執行效果會怎樣?
--測試環境
create table t1 as select object_id,object_name from dba_objects;
create table t2 as select object_id,object_name from user_objects;
create table t3 as select rownum object_id,table_name object_name from user_tables;
analyze table t1 compute statistics for table for all columns;
analyze table t2 compute statistics for table for all columns;
analyze table t3 compute statistics for table for all columns;
t1--49830;t2--37;t3--16
開始測試:
1.比較簡單的子查詢:子查詢中表直接和主表就有關聯關係
select /*+gather_plan_statistics*/
(select t2.object_name from t2 where t2.object_id = t1.object_id) object_name
from t1;
執行計劃:
---------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |
---------------------------------------------------------------------------------------------
|* 1 | TABLE ACCESS FULL| T2 | 49830 | 1 | 36 |00:00:01.75 | 149K| 0 |
| 2 | TABLE ACCESS FULL| T1 | 1 | 49830 | 49830 |00:00:00.30 | 3546 | 231 |
---------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("T2"."OBJECT_ID"=:B1)
這個執行很簡單,執行t1,然後根據t1返回行數決定t2掃描次數。
create table t1 as select object_id,object_name from dba_objects;
create table t2 as select object_id,object_name from user_objects;
create table t3 as select rownum object_id,table_name object_name from user_tables;
analyze table t1 compute statistics for table for all columns;
analyze table t2 compute statistics for table for all columns;
analyze table t3 compute statistics for table for all columns;
t1--49830;t2--37;t3--16
開始測試:
1.比較簡單的子查詢:子查詢中表直接和主表就有關聯關係
select /*+gather_plan_statistics*/
(select t2.object_name from t2 where t2.object_id = t1.object_id) object_name
from t1;
執行計劃:
---------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |
---------------------------------------------------------------------------------------------
|* 1 | TABLE ACCESS FULL| T2 | 49830 | 1 | 36 |00:00:01.75 | 149K| 0 |
| 2 | TABLE ACCESS FULL| T1 | 1 | 49830 | 49830 |00:00:00.30 | 3546 | 231 |
---------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("T2"."OBJECT_ID"=:B1)
這個執行很簡單,執行t1,然後根據t1返回行數決定t2掃描次數。
2.複雜點的子查詢:子查詢的子查詢和主表有關聯關係
select /*+gather_plan_statistics*/
(select t2.object_name
from t2
where t2.object_name in
(select t3.object_name from t3 where t1.object_id = t3.object_id)) object_name
from t1;
執行計劃:觀看執行次數和實際返回行數
----------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |
----------------------------------------------------------------------------------------------
|* 1 | FILTER | | 49830 | | 15 |00:00:39.89 | 5680K| 2 |
| 2 | TABLE ACCESS FULL| T2 | 49830 | 37 | 1843K|00:00:07.89 | 149K| 0 |
|* 3 | TABLE ACCESS FULL| T3 | 1843K| 1 | 15 |00:00:27.95 | 5531K| 2 |
| 4 | TABLE ACCESS FULL | T1 | 1 | 49830 | 49830 |00:00:00.20 | 3546 | 0 |
----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter( EXISTS (SELECT /*+ */ 0 FROM "T3" "T3" WHERE
"T3"."OBJECT_NAME"=:B1 AND "T3"."OBJECT_ID"=:B2))
3 - filter("T3"."OBJECT_NAME"=:B1 AND "T3"."OBJECT_ID"=:B2)
首先執行t1,然後執行t2,最後執行t3(從predicate中3可以看出,t3依賴於t1傳過來的引數object_id和t2傳過來的引數object_name)。
仔細分析下Starts和A-Rows發現,執行t1返回49830行,然後執行t2,由於t2和t1沒有任何關聯條件,導致執行t2後返回的行數是t2資料行數與t2執行次數(t1返回行數)相乘;
這也就直接影響到t3執行次數。也就是說不管t3中有多少行滿足條件的資料,都會對錶t3掃描t1和t2行數相乘次。而如果t1和t2返回行數相當大,那麼結果就可想而知了~
select /*+gather_plan_statistics*/
(select t2.object_name
from t2
where t2.object_name in
(select t3.object_name from t3 where t1.object_id = t3.object_id)) object_name
from t1;
執行計劃:觀看執行次數和實際返回行數
----------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |
----------------------------------------------------------------------------------------------
|* 1 | FILTER | | 49830 | | 15 |00:00:39.89 | 5680K| 2 |
| 2 | TABLE ACCESS FULL| T2 | 49830 | 37 | 1843K|00:00:07.89 | 149K| 0 |
|* 3 | TABLE ACCESS FULL| T3 | 1843K| 1 | 15 |00:00:27.95 | 5531K| 2 |
| 4 | TABLE ACCESS FULL | T1 | 1 | 49830 | 49830 |00:00:00.20 | 3546 | 0 |
----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter( EXISTS (SELECT /*+ */ 0 FROM "T3" "T3" WHERE
"T3"."OBJECT_NAME"=:B1 AND "T3"."OBJECT_ID"=:B2))
3 - filter("T3"."OBJECT_NAME"=:B1 AND "T3"."OBJECT_ID"=:B2)
首先執行t1,然後執行t2,最後執行t3(從predicate中3可以看出,t3依賴於t1傳過來的引數object_id和t2傳過來的引數object_name)。
仔細分析下Starts和A-Rows發現,執行t1返回49830行,然後執行t2,由於t2和t1沒有任何關聯條件,導致執行t2後返回的行數是t2資料行數與t2執行次數(t1返回行數)相乘;
這也就直接影響到t3執行次數。也就是說不管t3中有多少行滿足條件的資料,都會對錶t3掃描t1和t2行數相乘次。而如果t1和t2返回行數相當大,那麼結果就可想而知了~
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/24496749/viewspace-731888/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 34. 過濾條件、多表查詢、子查詢
- Laravel Eloquent ORM 多條件查詢,你會怎麼寫?LaravelORM
- 寫一個“特殊”的查詢構造器 – (四、條件查詢:複雜條件)
- mysql條件查詢MySql
- MongoDB查詢條件MongoDB
- Laravel 多條件查詢Laravel
- 20240719資料庫關聯查詢、條件查詢資料庫
- SQL-基礎語法 - 條件查詢 - 模糊查詢SQL
- Javaweb-DQL-條件查詢JavaWeb
- 查詢條件封裝物件封裝物件
- AntDesignBlazor示例——列表查詢條件Blazor
- SpringBoot Jpa多條件查詢Spring Boot
- mongodb條件查詢不等於MongoDB
- golang beego orm 查詢條件 or andGolangORM
- 【mybatis-plus】條件查詢MyBatis
- mysql多條件過濾查詢之mysq高階查詢MySql
- 執行計劃-6:推入子查詢
- SQL查詢的:子查詢和多表查詢SQL
- 複雜查詢—子查詢
- hyperf關聯模型條件查詢模型
- 菜品條件分頁查詢
- mysql拆分字串做條件查詢MySql字串
- Linq查詢之多個排序條件排序
- Linq兩個from查詢條件
- mysql like查詢 - 根據多個條件的模糊匹配查詢MySql
- 一條查詢語句的執行流程
- 增加子查詢表條件篩選提高效能
- mysql中一條查詢語句的執行全過程是怎樣的?MySql
- mysql-分組查詢-子查詢-連線查詢-組合查詢MySql
- MybatisPlus入門(五)MybatisPlus條件查詢MyBatis
- Vue請求介面查詢條件拼接Vue
- mybatis-plus QueryWrapper條件查詢器MyBatisAPP
- 多執行緒查詢執行緒
- MYSQL學習筆記25: 多表查詢(子查詢)[標量子查詢,列子查詢]MySql筆記
- 關於sqlserver字元型別查詢條件區分大小寫SQLServer字元型別
- 關聯查詢完,寫個 select 把條件放在外面,方便條件處理
- MySQL之連線查詢和子查詢MySql
- MySQL子查詢MySql
- 子串查詢