一次資料庫的優化經歷

xuexiaogang發表於2021-12-12

自己原文公眾號:

https://mp.weixin.qq.com/s/H5IEqcasnN4nCoipUauH1w


前幾天有個學員問我個SQL能不能優化。SQL如下:

SELECT S.CARD_NO  FROM  S  

WHERE S.DATE BETWEEN TO_DATE('20171002 00:00:00', 'yyyymmdd hh24:mi:ss') AND TO_DATE('20180701 23:59:59', 'yyyymmdd hh24:mi:ss')  

AND S.CARD_NO NOT IN  

   ( 

   SELECT P.CARD_NO  FROM  P  

   WHERE  P.DATE between to_date('20171002 00:00:00', 'yyyymmdd hh24:mi:ss')  and to_date('20210627 23:59:59', 'yyyymmdd hh24:mi:ss')

   )  

AND S.CARD_NO NOT IN  

   ( 

   SELECT s.CARD_NO  FROM s   

  AND s.DATE between to_date('20171002 00:00:00', 'yyyymmdd hh24:mi:ss')  and to_date('20210627 23:59:59', 'yyyymmdd hh24:mi:ss')

   )  


背景是

第一段的時間為2017年10月02日,到2018年07月01日。這個SQL要查詢的,就是這段時間內購買了的、並且截至2021年06月27日尚未兌換或退換的票券資訊。

 

第二段時間是從2017年10月2日,到2021年6月27日。排除這段時間內P表(兌換記錄表)中的資料;card_no not in,也就是把購買了並且已兌換的票券排除掉。

 

第三段時間是從2017年10月2日,到2021年6月27日。排除這段時間內S表(購買、退換貨記錄表)中的資料;card_no not in,就是把購買了但進行了退換的票券排除。

 

現在執行了3天半了,期望6小時。這個sql手動執行,晚上12點左右執行;2到3個月執行一次。


當我看到這個震驚了,雖然不是我見過最長的,但是執行3天半這個還是有點狠的。

 

    我第一感覺是要查有效期以外有多少沒兌換的要做失效處理。如果是我,我考慮這種有個有效期。一問說長期有效。其實這是不合理的。

    

S表 購買、退貨記錄 大約4億條資料,從2014年至今。而條件是要查S表一年的資料。符合條件的大約1000萬。(不科學)

P表  兌換記錄 大約9千萬條資料,符合條件的大約7000萬。

然後就是1000萬的看看不在7000萬中的有多少,然後再看看再排除自己範圍中“ 退換”的資料。退是在S表,兌換是在P表。有點抓狂,有點反人類。


在經歷了差集改寫也無效的情況下,總覺得這樣去返回幾百萬總歸是不快的。


    這個時候發揮一個無敵的想法,改實現方式。經過了解上次他們是執行過的。這就是為什麼結束時間都是2021年6月27日。那麼也就是說如果開始時間都是2017年10月2日,結束時間都是2021年6月27日(SQL上是這麼寫的),那麼7月10日以後執行從邏輯上來說,結果是一樣的。也就是說無需執行就用上次的結果就行。從邏輯上推斷上次的結果一定是匯出下載了,不可能查完算了。

     那麼不用執行就是最高境界,英雄中有句話,劍的三個境界。 第一層境界:手中有劍心中有劍第二層境界:手中無劍心中有劍第三層境界:手中無劍心中也無劍,那就是和平。優化的最高境界就是不做。

     題外話如果說時間改變了呢?也好辦。上次計算的結果落在表中,那麼這次只要看看2021年6月27日到今天的資料和上次結果的資料進行一下比較。沒多少的,幾天的資料總比幾年的資料快幾百倍吧。


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

相關文章