一週工作總結--左連線造成的一些問題

Joshua_q發表於2013-03-28

     今天有同事告訴我,有個SQL執行了好久好久執行不出來,我說好就是多久?她說一天左右了。真是令人咋舌的SQL。於是我要來了SQL看了看執行計劃,確實讓人咋舌。

     下圖中就是執行計劃的截圖:

     

     25G的COST和75T的Bytes確實是無法承受之重。這個SQL是這樣子的:

      

      select部分做了很多sum運算,還有distinct等運算,總之很麻煩,group by部分就是上面的維度。其中最大的表是TABLE3和TABLE4,這兩個表所需要查詢的資料量都在3G以上,各自差不多3000萬資料。

      最開始我以為是因為資料量大的原因導致的這個執行計劃不可實現,但是在我將TABLE3和TABLE4的相應資料進行壓縮後,資料量儘管各自降低到了1G左右,但是執行計劃基本上沒有改變,這不是我要的效果,於是我注意到了執行計劃中紅色框中的部分。是不是這裡導致了問題的發生?於是我開始檢視SQL,就發現了一個問題:TABLE4實際上只有201302的資料,但是為什麼這裡還需要在左連線的時候寫上月份標識,這個比較不合理,而且根據我以往的經驗判斷,左連線或者右連線的時候,如果and條件寫的太多,往往會影響執行計劃,導致SQL長久的無法得到結果。於是我做了一個很簡單的事情,就是把TABLE4的month_id部分去掉,後來我又進了一步,將TABLE3的month部分也去掉了,這是一個分割槽表,於是我用了這個辦法:

     left join TABLE3 partition(part_02),這樣即實現了減少and條件的目的,又不會影響資料準確的效果,一舉兩得。在進行了相關的優化之後,執行計劃變成了這個樣子:

    

     可以看到執行計劃發生了翻天覆地的變化,直接能看到的就是少了NESTED LOOPS OUTER,取而代之的是圖中1部分和2部分的HASH JOIN OUTER和TABLE1的HASH JOIN OUTER,這是我喜歡看到的事情,我就喜歡看到簡單的執行計劃。雖然這個COST依舊很大,但是我實在不想動彈了,這個的資料量實在是太巨大了,我面對的優化工作難度已經無法讓我有精力想過去那樣,仔細研究思考,然後把COST弄到幾千或者更小的程度了,就這樣吧,天要下雨,娘要嫁人,隨他去吧。

     我以前看到論壇上或者書上都在寫,如果你的表超過1G,那麼最好進行分割槽,這句話現在我深有體會,如果沒有分割槽表,這個SQL也沒有辦法優化了(或者說我就沒有能力去優化了),因為沒有辦法去掉month的條件,除非是將特定月份的資料取出來建立一箇中間表,不過那麼做似乎有點麻煩了,不符合我一貫喜歡寫短程式碼的習慣。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28207565/viewspace-757363/,如需轉載,請註明出處,否則將追究法律責任。

相關文章