SQL最佳化案例-使用with as最佳化Subquery Unnesting(七)
使用 no_unnest hint可以讓執行計劃產生filter,即不展開,但一般情況下使用unnest hint無法消除filter。
如下SQL,找出庫中非唯一索引,那麼大家可能會這麼寫SQL:
SELECT SEGMENT_NAME,SUM(BYTES/1024/1024) m FROM DBA_SEGMENTS WHERE SEGMENT_NAME NOT IN (select index_name from dba_indexes where UNIQUENESS ='NONUNIQUE') GROUP BY SEGMENT_NAME;
耗時一分鐘,為什麼這麼慢呢?在SQL語句where子查詢後有not in、not exists、in、exists時,CBO會嘗試將子查詢展開(unnest)消除filter,但是上面的例子CBO並沒有做到,下面我們看下執行計劃。
我們再看下在子查詢中加unnest hint的執行計劃:
SELECT SEGMENT_NAME,SUM(BYTES/1024/1024) m FROM DBA_SEGMENTS WHERE SEGMENT_NAME NOT IN (select /*+UNNEST */index_name from dba_indexes where UNIQUENESS ='NONUNIQUE') GROUP BY SEGMENT_NAME;
filter消除,CBO將基於資料字典底層的基表重新組合,使執行計劃變成hash joinanti,0.23秒便執行完成了。
下面我們再來看下透過with as materialize最佳化subquery unnesting的例子。
SQL如下:
select AREA_NAME,sum(reve) from t_order o where exists (select AREA_ID from t_customer c where nation = 'Aus' and c.AREA_ID = o.AREA_ID union select AREA_ID from f_customer f where nation = 'US' and f.AREA_ID <> o.f_area_id) group by AREA_NAME;
selectsum(bytes/1024/1024) M from dba_segments where segment_name ='F_CUSTOMER'; M ---------- 192
表F_CUSTOMER192M
執行計劃如下:
我們看到並不走索引,要近2個小時執行完成,透過建立組合索引,讓其走index_ffs
CREATE INDEX IDX_FFS_NATION_ID ONf_customer(AREA_ID,nation,0);
8分鐘執行完成,那麼還有沒有更好的辦法呢?
如下:
with x as ( select /*+ materialize */ AREA_ID from f_customer f where nation = 'US') select AREA_NAME,sum(reve) from t_order o where exists (select AREA_ID from t_customer c where nation = 'Aus' and c.AREA_ID = o.AREA_ID union select AREA_ID from x where x.AREA_ID <> o.f_area_id) group by AREA_NAME;
在FILTER中,NOT IN(NOT EXISTS)後的SQL語句多次執行,本來資料量就很大,每次都要執行一遍,結果可想而知。但是使用HINT MATERIALIZE和WITH AS 結合使用,把表中部分列實體化,執行過程中會建立基於檢視的臨時表。這樣就不會每次NOT EXISTS都去執行一遍大資料表的掃描或者大的索引快速掃描,並且當表的資料越大,表越寬,這樣的最佳化效果越明顯。
| 作者簡介
姚崇·沃趣科技高階資料庫技術專家
熟悉Oracle、MySQL資料庫內部機制,豐富的Oracle、MySQL故障診斷、效能調優、資料庫備份恢復、複製、高可用方案及遷移經驗。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28218939/viewspace-2218158/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- SQL優化案例-使用with as優化Subquery Unnesting(七)SQL優化
- Oracle優化案例-使用with as優化Subquery Unnesting(七)Oracle優化
- 使用SQL Profile進行SQL最佳化案例SQL
- Oracle 查詢轉換-04 Subquery UnnestingOracle
- SQL最佳化案例-正確的使用索引(二)SQL索引
- sql最佳化:使用sql profile最佳化sql語句SQL
- SQL最佳化案例-union代替or(九)SQL
- ORACLE SQL效能最佳化系列 (七) (轉)OracleSQL
- Sql 巢狀迴圈最佳化案例SQL巢狀
- SQL最佳化案例-單表分頁語句的最佳化(八)SQL
- Oracle某行系統SQL最佳化(案例四)OracleSQL
- DM 傳統行業SQL最佳化案例行業SQL
- SQL最佳化案例一則--複合索引沒有被使用SQL索引
- 真實世界SQL最佳化案例2_訪問路徑最佳化SQL
- SQL最佳化案例-自定義函式索引(五)SQL函式索引
- Oracle某X系統SQL最佳化(案例六)OracleSQL
- Oracle SQL 'or' 的最佳化,最近的案例一則。OracleSQL
- 某保險理賠核心OB SQL最佳化案例SQL
- SQL最佳化SQL
- SQL最佳化案例-從執行計劃定位SQL問題(三)SQL
- 網站最佳化的七大最佳化方式網站
- union all 最佳化案例
- 使用sql tuning advisor最佳化sqlSQL
- 【SQL最佳化】SQL最佳化的10點注意事項SQL
- SQL最佳化 | MySQL問題處理案例分享三則MySql
- SQL最佳化案例-分割槽索引之無字首索引(六)SQL索引
- SQL效能最佳化之索引最佳化法SQL索引
- 效能最佳化之SQL語句最佳化SQL
- Oracle效能最佳化之SQL最佳化(轉)OracleSQL
- SQL最佳化1SQL
- PL/SQL最佳化SQL
- sql最佳化(mysql)MySql
- SQL最佳化方案SQL
- sql最佳化技巧SQL
- 幫任總DBA太太最佳化條金融SQL案例(DM資料庫案例)SQL資料庫
- 微課sql最佳化(17)、不改程式碼,最佳化SQL(1)-最佳化方法總結SQL
- OB案例、金融行業核心系統跑批SQL最佳化行業SQL
- 小米 sql 最佳化工具SQL