在sql查詢中為了提高查詢效率,我們常常會採取一些措施對查詢語句進行sql優化,下面總結的一些方法,有需要的可以參考參考。在某運營商的最佳化經驗中曾經遇到了一個比較有趣的SQL,具體如下:
1 這個最開始的sql 執行情況如下
SQL> SELECT 2 NVL(T.RELA_OFFER_SPEC_ID, SUBOS.SUB_OFFER_SPEC_ID) "offerSpecId" 3 FROM OFFER_SPEC_RELA T 4 LEFT JOIN OFFER_SPEC_GRP_RELA SUBOS 5 ON T.RELA_GRP_ID = SUBOS.OFFER_SPEC_GRP_ID 6 AND subos.start_dt <= SYSDATE 7 AND subos.end_dt >= SYSDATE 8 WHERE T.RELA_TYPE_CD = 2 9 AND t.start_dt <= SYSDATE 10 AND t.end_dt >= SYSDATE 11 AND (T.OFFER_SPEC_ID = 109910000618 12 OR EXISTS 13 (SELECT A.OFFER_SPEC_GRP_ID 14 FROM OFFER_SPEC_GRP_RELA A 15 WHERE A.SUB_OFFER_SPEC_ID = 109910000618 16 AND T.OFFER_SPEC_GRP_ID = A.OFFER_SPEC_GRP_ID 17 )) 18 AND rownum<500; no rows selected Execution Plan ---------------------------------------------------------- Plan hash value: 1350156609
Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter(ROWNUM<500) 2 - filter("T"."OFFER_SPEC_ID"=109910000618 OR EXISTS (SELECT 0 FROM "SPEC"."OFFER_SPEC_GRP_RELA" "A" WHERE "A"."OFFER_SPEC_GRP_ID"=:B1 AND "A"."SUB_OFFER_SPEC_ID"=109910000618)) 3 - access("T"."RELA_GRP_ID"="SUBOS"."OFFER_SPEC_GRP_ID"(+)) 4 - filter("T"."RELA_TYPE_CD"=2 AND "T"."END_DT">=SYSDATE@! AND "T"."START_DT"<=SYSDATE@!) 5 - filter("SUBOS"."END_DT"(+)>=SYSDATE@! AND "SUBOS"."START_DT"(+)<=SYSDATE@!) 6 - access("A"."SUB_OFFER_SPEC_ID"=109910000618 AND "A"."OFFER_SPEC_GRP_ID"=:B1) Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 12444 consistent gets 0 physical reads 0 redo size 339 bytes sent via SQL*Net to client 509 bytes received via SQL*Net from client 1 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 0 rows processed PLAN GET DISK WRITE ROWS ROWS USER_IO(MS) ELA(MS) CPU(MS) CLUSTER(MS) PLSQL END_TI I HASH VALUE EXEC PRE EXEC PRE EXEC PER EXEC ROW_P PRE EXEC PRE FETCH PER EXEC PRE EXEC PRE EXEC PER EXEC PER EXEC
2 第一次分析
此時應該有下列地方值得注意
1) 該sql 每天執行上千次,平均每次執行回傳不到10 行數據,但平均邏輯讀達到1.2W,可能有效能問題。
2)ID 為 4,5 的執行計劃路徑中出現了兩個全表掃描,看到這兒我們可以想到可能是沒有合適的索引導致走了全表掃描從而執行效率低下。
3)ID 為2 的執行計劃路徑出現了FILTER,且3,和6 為其子路徑,如果FILTER有兩個及兩個以上的子路徑,那麼他的執行原理將類似於嵌套循環,id 號最小的子路徑如果返回行數較多,可能會導致多次執行id號較小的子路徑,導致效能低。一般存在 “OR EXISTS” 的時候會出現此情況,可以根據情況避免。
相關連結:
以上是SQL優化:很簡單的一篇提高SQL效能的文章!的詳細內容。更多資訊請關注PHP中文網其他相關文章!