一個NOT EXISTS含有OR條件子查詢的優化
SQL> SELECT COUNT(*) FROM TC2_SEG S WHERE S.PART_ID = 11 AND S.CLASS_ID IN (310,510)
2 AND NOT EXISTS (SELECT NODEID FROM TEMP_PORTNODE WHERE NODEID=S.HEAD_NODE OR NODEID=S.TAIL_NODE);
執行計劃
----------------------------------------------------------
Plan hash value: 3774119106
-------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 23 | 102K (1)| 00:20:30 |
| 1 | SORT AGGREGATE | | 1 | 23 | | |
|* 2 | FILTER | | | | | |
|* 3 | TABLE ACCESS FULL| TC2_SEG | 54783 | 1230K| 581 (1)| 00:00:07 |
|* 4 | TABLE ACCESS FULL| TEMP_PORTNODE | 73598 | 1850K| 2 (0)| 00:00:01 |
-------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter( NOT EXISTS (SELECT 0 FROM "TEMP_PORTNODE" "TEMP_PORTNODE"
WHERE "NODEID"=:B1 OR "NODEID"=:B2))
3 - filter(("S"."CLASS_ID"=310 OR "S"."CLASS_ID"=510) AND
"S"."PART_ID"=11)
4 - filter("NODEID"=:B1 OR "NODEID"=:B2)
這個SQL跑了16分鐘,從執行計劃看到走FILTER,效率極低,,原因是子查詢WHERE中包含了OR。
嘗試將SQL改為:
SQL> SELECT COUNT(*) FROM TC2_SEG S WHERE S.PART_ID = 11 AND S.CLASS_ID IN (310,510)
2 AND NOT EXISTS (SELECT NODEID FROM TEMP_PORTNODE WHERE NODEID=S.HEAD_NODE )
3 AND NOT EXISTS (SELECT NODEID FROM TEMP_PORTNODE WHERE NODEID=S.TAIL_NODE );
執行計劃
----------------------------------------------------------
Plan hash value: 3386542280
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 49 | 587 (1)| 00:00:08 |
| 1 | SORT AGGREGATE | | 1 | 49 | | |
|* 2 | HASH JOIN RIGHT ANTI | | 54781 | 2621K| 587 (1)| 00:00:08 |
| 3 | TABLE ACCESS FULL | TEMP_PORTNODE | 73598 | 1850K | 2 (0)| 00:00:01 |
|* 4 | HASH JOIN RIGHT ANTI| | 54782 | 1925K| 584 (1)| 00:00:08 |
| 5 | TABLE ACCESS FULL | TEMP_PORTNODE | 73598 | 1850K | 2 (0)| 00:00:01 |
|* 6 | TABLE ACCESS FULL | TC2_SEG | 54783 | 1230K| 581 (1)| 00:00:07 |
----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("NODEID"="S"."HEAD_NODE")
4 - access("NODEID"="S"."TAIL_NODE")
6 - filter(("S"."CLASS_ID"=310 OR "S"."CLASS_ID"=510) AND "S"."PART_ID"=11)
1秒跑完,從執行計劃看,子查詢UNNEST了,選擇了HASH JOIN RIGHT ANTI,原SQL由於子查詢WHERE中含又OR導致無法UNNEST。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22990797/viewspace-1294341/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- exists與in子查詢優化優化
- 寫一個“特殊”的查詢構造器 – (四、條件查詢:複雜條件)
- 34. 過濾條件、多表查詢、子查詢
- 【MySQL】NOT EXISTS優化的一個案例MySql優化
- Linq查詢之多個排序條件排序
- Linq兩個from查詢條件
- mysql條件查詢MySql
- MongoDB查詢條件MongoDB
- mysql like查詢 - 根據多個條件的模糊匹配查詢MySql
- Laravel 多條件查詢時粗心導致的一個 BUGLaravel
- 同一欄位多個查詢條件時遇到的一個問題
- MySQL exists關聯子查詢SQL效能及其低下最佳化之等值子查詢轉換MySql
- 一文終結SQL 子查詢優化SQL優化
- Laravel 多條件查詢Laravel
- 增加子查詢表條件篩選提高效能
- SpringBoot Jpa多條件查詢Spring Boot
- AntDesignBlazor示例——列表查詢條件Blazor
- golang beego orm 查詢條件 or andGolangORM
- Javaweb-DQL-條件查詢JavaWeb
- 查詢條件封裝物件封裝物件
- mongodb條件查詢不等於MongoDB
- 【mybatis-plus】條件查詢MyBatis
- mysql求交集:UNION ALL合併查詢,inner join內連線查詢,IN/EXISTS子查詢MySql
- KunlunDB 查詢優化(一)優化
- Mysql優化系列之——優化器對子查詢的處理MySql優化
- 查詢滿足條件的最新資料(逐步優化,mysql、達夢資料庫)優化MySql資料庫
- elasticsearch之exists查詢Elasticsearch
- 優化 JS 條件語句的 5 個技巧優化JS
- 20240719資料庫關聯查詢、條件查詢資料庫
- 為什麼所有的查詢條件都命中索引還是那麼慢?記一次慢查詢優化過程索引優化
- 菜品條件分頁查詢
- hyperf關聯模型條件查詢模型
- mysql拆分字串做條件查詢MySql字串
- PostgreSQL一複合查詢SQL優化例子-(多個exists,範圍檢索,IN檢索,模糊檢索組合)SQL優化
- 關聯查詢完,寫個 select 把條件放在外面,方便條件處理
- SQL-基礎語法 - 條件查詢 - 模糊查詢SQL
- 查詢條件和條數,先查詢兩條免費的,後面為vip
- PostgreSQL 原始碼解讀(29)- 查詢語句#14(查詢優化-上拉子查詢)SQL原始碼優化
- Java 條件表示式的優化Java優化