在某客戶現場發現了一個執行了很長時間(15.8小時)仍未執行完的SQL,並且SQL使用了8個並行進程:sql
SQL代碼以下:性能優化
SELECT /*+ PARALLEL(a,8)*/ count(: "SYS_B_0")微信
FROM so1.ins_srv_attr_780 aoracle
WHERE a.offer_inst_id IN 性能
(優化
SELECT /*+parallel(b,8)*/ b.offer_inst_idspa
FROM so1.ins_offer_780 b.net
WHERE b.offer_type = : "SYS_B_1"3d
) AND進程
a.prod_srv_relat_id NOT IN
(
SELECT c.prod_srv_relat_id
FROM so1.ins_prod_ins_srv_780 c
);
SQL包含一個IN和一個NOT IN,執行計劃中not in的filter步驟效率低,並且這一步還漏寫了並行hint(不是主要問題)。爲何優化器會選擇這樣低效的執行計劃?
客戶修改了多個隱含參數:
OPT_PARAM('_optimizer_use_feedback' 'false')
OPT_PARAM('_optimizer_join_factorization' 'false')
OPT_PARAM('_optimizer_enable_density_improvements' 'false')
OPT_PARAM('_optimizer_adaptive_cursor_sharing' 'false')
OPT_PARAM('_optimizer_extended_cursor_sharing_rel' 'none')
OPT_PARAM('_bloom_pruning_enabled' 'false')
OPT_PARAM('_gby_hash_aggregation_enabled' 'false')
OPT_PARAM('_optimizer_join_elimination_enabled' 'false')
OPT_PARAM('_optimizer_extended_cursor_sharing' 'none')
OPT_PARAM('_bloom_filter_enabled' 'false')
OPT_PARAM('_optimizer_squ_bottomup' 'false')
通過執行排查,發現其中的罪魁禍首就_optimizer_squ_bottomup:
咱們來看看這個參數爲默認TRUE的時候SQL的執行狀況(順便修正了並行寫法問題):
SELECT /*+ PARALLEL(8) OPT_PARAM('_optimizer_squ_bottomup' 'true') */ count(1)
FROM so1.ins_srv_attr_780 a
WHERE a.offer_inst_id IN
(
SELECT b.offer_inst_id
FROM so1.ins_offer_780 b
WHERE b.offer_type = 'OFFER_PLAN_BBOSS'
) AND a.prod_srv_relat_id NOT IN
(
SELECT c.prod_srv_relat_id
FROM so1.ins_prod_ins_srv_780 c
);
效果直接看下圖:
系統參數,尤爲是隱含參數,在沒有遇到bug的狀況下,通常不建議修改,這個案例就是很是明顯的一個教訓。
本文分享自微信公衆號 - 老虎劉談oracle性能優化(sql_tigerliu)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。