SQL查詢速度慢?舍棄''in''和''not in'',讓你的數(shù)據(jù)庫飛起來
當(dāng)前位置:點晴教程→知識管理交流
→『 技術(shù)文檔交流 』
引言最近在重構(gòu)一個老項目時,被一段SQL查詢卡得死死的,排查下來才發(fā)現(xiàn)是 IN 和 NOT IN 惹的禍。雖然這兩個關(guān)鍵字看著挺順手,寫起來也方便,但我今天就來說說為啥真正的開發(fā)老司機(jī)都悄悄拋棄了它們。 性能差到驚人:一個血的教訓(xùn)前段時間我在處理用戶數(shù)據(jù)同步時遇到個情況:users表和user_profiles表都是90萬條數(shù)據(jù)左右,大概300MB,完全算不上大表。結(jié)果我隨手寫了句:
這條查詢直接把我整懵了...跑了幾分鐘還沒出結(jié)果!檢查后發(fā)現(xiàn)mobile字段在兩個表都建了索引,類型也完全一致。執(zhí)行explain后才知道,原來NOT IN這種操作方式?jīng)]走索引,難怪這么慢。改成了EXISTS后,整個世界都清靜了:
僅僅十幾秒就跑完了,簡直天壤地別! 最坑的是:它不會明確報錯,讓你吃暗虧除了慢,IN/NOT IN還有個更惡心的問題:容易寫錯但不會報錯,查出來的結(jié)果還看著像那么回事。我用兩個簡單的表來演示:
如果我想找出在departments表中存在的員工ID,正常應(yīng)該這么寫:
結(jié)果很正常:返回1和2。但假如我手抖寫成了:
注意看,我把子查詢里的dept_id寫成了emp_id。魔幻的是,這句SQL居然不報錯!直接返回了1、2、3所有數(shù)據(jù)!更扯的是,如果單獨執(zhí)行 老司機(jī)都用啥替代方案?既然IN和NOT IN這么不靠譜,咱們就用更穩(wěn)的方案: 方案一:EXISTS/NOT EXISTS
方案二:JOIN大法
這兩種方法不僅性能好,而且對NULL的處理也更加合理,不會搞出莫名其妙的結(jié)果。 說真的,少用IN和NOT IN吧看完這些例子,我是再也不敢隨便用IN和NOT IN了。雖然它們看起來簡單直觀,寫起來也省事,但隱藏的坑實在太多。特別是在處理大量數(shù)據(jù)的時候,性能差異簡直就是天壤之別。如果你們團(tuán)隊的代碼庫里還有這種寫法,趕緊改掉吧!別等到生產(chǎn)環(huán)境出了問題才來查原因。 該文章在 2025/4/11 10:15:48 編輯過 |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |