一次優化記錄

2022-02-24 07:13:01 字數 1611 閱讀 1112

今天收到乙個同事的求助,說有乙個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

notexists

(select **號碼 from 表2 t2 where t1.**號碼 =

t2.**號碼)

group

by **號碼, 列2, 列3, flag;

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

我看了一下原本sql的執行計畫:

我發現全表掃瞄耗用很大。查詢一下資料,發現這是一張客戶資訊表,所有人的**號碼都是不同的,因此我想到了將這個表改成乙個雜湊分割槽表。至於為什麼會想到雜湊分割槽表,參考我以前寫過的:

我建立了一張雜湊分割槽表:表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有不同的優化方法,冷靜的分析,運用自己學過的技術,總能把調優做的很好。

一次優化記錄

備註 由於隱私 部分使用了偽 偽sql 直接查十點查全部 select from 使用者優惠券表 where 優惠券id in select id from 優惠券表 where 限制 新使用者 and 90天內 總時間40 秒 這裡用exlpain分析 優惠券id是有索引的,但是實際上沒有走索引。...

一次優化經歷

問題 excel資料匯入,儲存到資料庫中,為了優化查詢效率和其他一些業務需求,需要將資料的一列屬性切分後儲存到redis中,插入資料庫前要保證其中乙個屬性不重複,另外乙個屬性已經在資料庫中。為了將問題描述簡單些,我們假設excel中有兩列資料a和b,其中資料a要保證資料庫中不重複,資料b保證資料庫中...

一次優化web專案的經歷記錄(二)

前言 最近很長一段時間沒有更新部落格了,忙於一堆子專案的開發,嚴重拖慢了學習與思考的程序。開水倒滿了需要提早放下杯子,晚了就會燙手,這段時間以來,寫的東西越來越不嚴謹,各種低階錯誤頻出,早該停下總結並鞏固一下了。但出於一些原因一直沒付諸於行,終於,燙到手了 在python裡,這很容易實現,借助裝飾器...