一次優化記錄


    今天收到一個同事的求助,說有一個SQL跑了一個多小時沒有結果。我看了看,這個SQL是這樣的(隱藏了敏感信息):

    

SELECT 電話號碼, 列2, 列3, MAX(STARTTIME), FLAG
  FROM 表1 T1
 WHERE FLAG = '0'
   AND 電話號碼 NOT IN (SELECT 電話號碼 FROM 表2 T2)
 GROUP BY 電話號碼, 列2, 列3, FLAG;

     我首先查看了兩個表的數據量,表1有將近300萬條,表2有不到10萬條記錄。並不是很大的數據。於是我關注到了not in,這個語句是幾乎所有的優化指南上都明確說了要避免的語句。於是我就把這句改了,改成了not exists:

    

SELECT 電話號碼, 列2, 列3, MAX(STARTTIME), FLAG
  FROM 表1_新 T1
 WHERE FLAG = '0'
   AND NOT EXISTS
 (SELECT 電話號碼 FROM 表2 T2 WHERE T1.電話號碼 = T2.電話號碼)
 GROUP BY 電話號碼, 列2, 列3, FLAG;

 

     但是COST僅僅降低到了原來的五分之一,這遠遠不是我需要的。我需要的是質一樣的飛躍。

     我看了一下原本SQL的執行計划:

     

       我發現全表掃描耗用很大。查詢一下數據,發現這是一張客戶信息表,所有人的電話號碼都是不同的,因此我想到了將這個表改成一個哈希分區表。至於為什么會想到哈希分區表,參考我以前寫過的:http://www.cnblogs.com/wingsless/archive/2012/09/28/2707661.html

       我建立了一張哈希分區表:表1_新。

       這個時候我用剛才改的語句,然后看看執行計划:

       

      這個效果就非常好了,36847的COST和2684K的COST比起來簡直是天壤之別。實際測試一下,查詢出所有的數據僅僅需要55秒。

      如果不用not exists,在哈希分區表上用原來的SQL查查,執行計划是這樣的:

      

      可以看到COST會有下降,但是僅僅是一半左右,這也不是優化所要達到的目的。

      其實這次SQL優化的主要在於使用了not exists。因為在三個執行計划中,最開始的對表1或者表1_新的掃描,COST都不到20000,而且很接近,因此哈希分區應該並不是提升效率的關鍵。至於效率為什么提高,這句是關鍵:access("T1"."電話號碼"="T2"."電話號碼")。關於not in和not exists的優劣區別,今天太晚了,周末再好好寫寫吧。 

      有幾次同事問我怎么去優化?其實優化,我覺得並沒有什么技巧,應該就和踢足球一樣,沒有什么戰無不勝的踢法,只有對場上局面冷靜的分析,隨時調整戰法,才能無往而不利,這樣才是好的教練,這應該就是穆里尼奧的本事。優化也是這樣的,不同的SQL有不同的優化方法,冷靜的分析,運用自己學過的技術,總能把調優做的很好。


免責聲明!

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



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