在一些業務場景中,會使用not exists語句確保返回資料不存在於特定集合,部分同事會發現not exists有些場景效能較差,甚至有些網上謠言說」not exists不走索引」,哪對於not exists語句,我們如何優化呢?
以今天優化的sql為例,優化前sql為:
select count(1)
from t_monitor m
where not exists (
select 1
from t_alarm_realtime as a
where a.resource_id=m.resource_id
and a.resource_type=m.resource_type
and a.monitor_name=m.monitor_name
)我們使用left join方式進行優化,優化後sql為:
select count(1)
from t_monitor m
left join t_alarm_realtime as a
on a.resource_id=m.resource_id
and a.resource_type=m.resource_type
and a.monitor_name=m.monitor_name
where a.resource_id is null
優化效果:
優化前執行時間29秒以上,優化後1.2秒,優化提公升25倍。
not exists真的不走索引麼?
檢視兩種sql的執行計畫!
使用not exist方式的執行計畫:
使用left join方式的執行計畫:
從執行計畫來看,兩個表都使用了索引,區別在於not exists使用「dependent subquery」方式,而left join使用普通表關聯的方式。
通過mysql提供的profiling方式來檢視兩種方式的執行過程。
使用not exist方式的執行過程:
使用left join方式的執行過程:
從執行過程來看,left join方式的主要消耗在sending data一項上(1.2s),而not exists方式主要消耗在executeing和sending data兩項上,受限於profiling只存放100行記錄緣故。
從profiling中只能看到47個」 executeing和sending data」的組合項(每個組合項約50us),通過執行計畫看出,外表t_monitor的資料量為578436行,忽略統計資訊不准情況下,使用not exists方式應該會產生578436個」 executeing和sending data」的組合項,總計消耗時間=50μs*578436=28921800us=28.92s。
從上面執行過程可以推斷出:
使用not exists方式的執行效能嚴重依賴於not exists子查詢的執行次數即外層查詢結果集的資料量。
當外層查詢結果集的資料量n較小時執行效能較好,如有n=10執行時間為50μs*10=500us=0.005s,再加上一些額外消耗,執行結果也能在0.01秒或10毫秒內範圍,這個響應時間應該能被大部分應用程式接受。
當外層程勳結果集的資料量n較大甚至上千萬資料量時,not exists的查詢效能會變得非常糟糕,甚至會大量消耗伺服器io和cpu資源從而影響其他業務正常執行。
除上述問題外,在優化過程中發現本應該儲存相同資料的resource_id列在兩個表中定義不同,一表為varchar而另外一表為bigint,外部結果集的字段型別和not exist字表中欄位型別不同導致not exists子查詢中無法使用索引,使得子查詢效能較差,最終影響整個查詢的執行效能。
猜你喜歡
1、github 標星 3.2w!史上最全技術人員面試手冊!fackboo發起和總結
2、如何才能成為優秀的架構師?
3、從零開始搭建創業公司後台技術棧
4、程式設計師一般可以從什麼平台接私活?
5、37歲程式設計師被裁,120天沒找到工作,無奈去小公司,結果懵了...
6、滴滴業務中臺構建實踐,首次**
7、不認命,從10年流水線工人,到谷歌上班的程式媛,一位湖南妹子的勵志故事
8、15張圖看懂瞎忙和高效的區別
9、2t架構師學習資料乾貨分享
MySQL NOT EXISTS優化的乙個案例
exists是對外表作loop迴圈,每次loop迴圈再對內表進行查詢,在專案中遇到類似的問題,資料量大時,not exists不管用並且執行sql的時間很長,在網上查了一些資料,所以記錄下來 原始sql explain select relation.id,relation.invited code...
無線充電寶,真忽悠還是真需求?
來自網路 文 魏啟揚 手機廠商又開始了新一輪的圈地運動。先是小公尺在最新旗艦機型小公尺9的上市發布會上推出了主打無線充電的移動電源 接著,三星在美國舊金山舉行的galaxy unpacked 2019新品發布會上曝出獲得fcc認證10000mah無線充電移動電源的外形和部分特性 在剛剛結束的wmc上...
真 生活你好
最近發現自己的一些問題。問題一直都在,只是之前的自己 不願意去面對罷了。諸如做事情不能堅持,容易煩躁,受不得人的逆耳忠言。自己想要成為什麼樣的人,現在明顯是沒有做到的。太容易懈怠了。meiya說人必須選擇一種生活方式並有勇氣堅持下去。最糟糕的狀態是明明你想選擇的是一條不甘於平庸,改變 進取和奮鬥的道...