oracle update from多表性能優化一例


這幾天測試java內存數據庫,和oracle比較時發下一個update from語句很慢,如下:

update business_new
           set fare1_balance_ratio = (select BALANCE_RATIO             from bfare2
                   where bfare2.exchange_type = business_new.exchange_type and
                         bfare2.stock_type = business_new.stock_type and
                         (bfare2.entrust_way = business_new.entrust_way) and
                         (bfare2.entrust_type = business_new.entrust_type) 
        and bfare2.fare_type = '0')

執行計划是這樣的:

從執行計划可以看出,走的就是nl關聯,所以慢是正常的。

於是將其改寫為merge,如下:

merge into business_new using bfare2
on (bfare2.exchange_type = business_new.exchange_type and
                         bfare2.stock_type = business_new.stock_type and
                         (bfare2.entrust_way = business_new.entrust_way) and
                         (bfare2.entrust_type = business_new.entrust_type) 
        and bfare2.fare_type = '4')
        when matched then update
           set business_new.farex_balance_ratio = bfare2.BALANCE_RATIO

改寫后執行計划如下:

很快就跑出來了。需要注意的是,update語句本身是通過hint讓兩表強制走hash join的。

除了用merge改寫讓兩表關聯走hash join外,還有一種更優、但有條件的做法。如下:

update (select fare1_balance_ratio,BALANCE_RATIO from business_new,bfare2
 where bfare2.exchange_type = business_new.exchange_type and
                         bfare2.stock_type = business_new.stock_type and
                         (bfare2.entrust_way = business_new.entrust_way) and
                         (bfare2.entrust_type = business_new.entrust_type) 
        and bfare2.fare_type = '0')
           set fare1_balance_ratio = BALANCE_RATIO ;

這也稱為inline view更新法,性能是最好的,但相比merge並不明顯。但表B的主鍵一定要在where條件中,並且是以“=”來關聯被更新表,否則會遇到ORA-01779: 無法修改與非鍵值保存表對應的列。造成這個錯誤的原因是更新的列不是事實表的列,而是維度表的列。換句話說,如果兩張表關聯,其中一張表的關聯列是主鍵,那么另一張表就是事實表,也就是說另一張表中的列就是可更新的;除非另一張表的關聯列也是主鍵,否則這張表就是不可更新的,如果更新語句涉及到了這張表,就會出現ORA-1799錯誤。也就是,要么兩張表都通過PK關聯,要么只有非PK這張表可更新。

至於for循環,乖乖,除非邏輯特別復雜,用for bulk collect,否則不要考慮。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM