MySQL數(shù)據(jù)庫社招必考題:索引如何優(yōu)化WHERE子句?
大家好,我是小米,一個31歲、天天被面試題支配的社畜程序員。最近后臺有小伙伴跟我說:“小米,你能不能聊聊 WHERE子句優(yōu)化?上次面試官問我,我一緊張就只說了‘建索引’,結果當場涼透了。”
哈哈,這個問題我太有感觸了!因為我當年第一次參加社招面試的時候,面試官問的第一個SQL問題就是:
“如果SQL語句的WHERE子句效率很低,你會怎么優(yōu)化?”
我當時也是秒答:“建索引啊!”結果面試官笑了笑,說:“嗯,光會說這個,說明你只停留在表面。”那一刻,我才意識到:優(yōu)化WHERE子句遠遠不只是建個索引那么簡單。
今天這篇文章,就帶大家從面試題的角度,系統(tǒng)聊聊 如何優(yōu)化WHERE子句,不僅告訴你該怎么答題,還會順帶幫你理清思路,以后再遇到類似問題,你能胸有成竹地侃侃而談。
解題方法:面試官想聽什么?
面試官拋出這個問題,本質(zhì)上是考察你兩點:
1、是否具備定位低效SQL的能力
你得知道,SQL變慢的根源在哪。是不是走了全表掃描?是不是索引沒用上?是不是數(shù)據(jù)量爆炸?
2、是否有系統(tǒng)化的優(yōu)化思路
面試官要聽的不是你一上來就說“加索引”,而是希望你能有邏輯:
- 先定位SQL語句是否低效;
- 再分析低效的原因;
- 最后給出逐步優(yōu)化的方案。
所以,正確的解題框架應該是:
第一步:定位低效SQL
- 打開慢查詢?nèi)罩荆╯low query log),確認問題SQL。
- 用 EXPLAIN 查看執(zhí)行計劃,看是否走了索引、是否出現(xiàn) ALL(全表掃描)。
第二步:分析原因
- 索引缺失?
- WHERE子句里用了不合適的寫法?
- 數(shù)據(jù)訪問量過大?
- 還是語句本身過于復雜?
第三步:逐項排查,提出優(yōu)化方法
- 索引問題 → 建合適的索引。
- 語句寫法問題 → 調(diào)整寫法,避免函數(shù)/表達式。
- 數(shù)據(jù)訪問問題 → 限制列數(shù)、分頁優(yōu)化。
- 特定情況 → 用全文索引、分庫分表、緩存。
這樣答題,面試官會覺得你有方法論,而不是只會背八股文。
接下來我們進入實戰(zhàn)。WHERE子句為什么會慢?我整理了10個常見場景,面試時直接說出來,絕對加分。
缺少索引或索引沒用上
問題:查詢條件的列沒有索引,或者索引被寫法“廢掉了”。
優(yōu)化:在 WHERE、ORDER BY、GROUP BY 常用列上建合適的索引。
舉例:

在 age 上建索引,就能避免全表掃描。
WHERE子句對字段進行 NULL 判斷
問題:

這種寫法,索引基本無效。
優(yōu)化:用默認值替代 NULL,或者在設計表時避免 NULL。
使用 != 或 <>
問題:

會導致引擎放棄索引,轉為全表掃描。
優(yōu)化:用范圍查詢代替,比如:

使用 OR 連接條件
問題:

大概率會導致全表掃描。
優(yōu)化:用 UNION ALL 拆開兩條SQL,再加索引。
濫用 IN 和 NOT IN
問題:

范圍太大時會拖慢查詢。
優(yōu)化:
- 用 EXISTS 替代。
- 或者把大范圍數(shù)據(jù)拆成小批次。
模糊查詢 %xxx%
問題:

前置 %,索引直接失效。
優(yōu)化:
- 改成 name like '小米%';
- 用全文索引(FULLTEXT)。
WHERE子句里用參數(shù)
問題:

參數(shù)在編譯時未知,優(yōu)化器沒法用索引。
優(yōu)化:用存儲過程或拼接SQL。
對字段做表達式操作
問題:

amount 上的索引會失效。
優(yōu)化:改寫成:

對字段做函數(shù)操作
問題:

同樣廢掉索引。
優(yōu)化:改寫成:

在 = 左邊使用函數(shù)或運算
問題:

索引無效。
優(yōu)化:改成:

WHERE子句優(yōu)化思路:一個小故事
給大家講個真實的小插曲。
之前我們項目里有個報表查詢,SQL長這樣:

一跑就卡,幾十萬行數(shù)據(jù),跑了30秒。
后來我們排查發(fā)現(xiàn):
- year(join_date) 把索引廢掉了。
- order by salary desc 沒索引,導致額外排序。
于是我們做了兩步優(yōu)化:
- 改寫SQL,把函數(shù)去掉:

- 給 salary 建索引。
結果呢?SQL從30秒縮短到不到1秒!老板看了直接夸:“小米,SQL優(yōu)化小能手!”
這件事給我一個啟發(fā):SQL優(yōu)化不是玄學,而是細節(jié)的積累。
總結:答題萬能公式
面試時如果被問到“如何優(yōu)化WHERE子句”,你完全可以用下面這個萬能公式來回答:
- 先定位問題:開啟慢查詢?nèi)罩?,?EXPLAIN 看執(zhí)行計劃。
- 從索引入手:WHERE、ORDER BY、GROUP BY 列上建索引。
- 排查寫法問題:避免 !=、<>、OR、IN、NOT IN、前置 %、函數(shù)/表達式操作等。
- 優(yōu)化特定情況:用全文索引、分批查詢、改寫SQL。
- 逐層遞進:從索引 → 數(shù)據(jù)訪問 → 語句寫法 → 特殊優(yōu)化。
這樣一套邏輯說下來,面試官絕對會覺得:哇,這小伙子有經(jīng)驗、有思路,不是只會背書。
最后的話
寫到這里,我想說,SQL優(yōu)化其實是一種“武功修煉”。一開始你可能只會用“索引”這把大刀亂砍,但隨著經(jīng)驗積累,你會學會更精細的招式,比如改寫SQL、利用執(zhí)行計劃、選擇合適的存儲結構。
所以,下次面試官再問你“如何優(yōu)化WHERE子句”,別慌。微微一笑,然后用今天學到的這套邏輯回答,保證能讓面試官眼前一亮!
END
那么,小伙伴們,你們在工作中有沒有遇到過 WHERE子句優(yōu)化的坑?比如寫了個模糊查詢結果全表掃描?歡迎在評論區(qū)分享你的故事,我們一起探討!
我是小米,一個喜歡分享技術的31歲程序員。如果你喜歡我的文章,歡迎關注我的微信公眾號“軟件求生”,獲取更多技術干貨!
到此這篇關于MySQL數(shù)據(jù)庫社招必考題:索引如何優(yōu)化WHERE子句?的文章就介紹到這了,更多相關Mysql數(shù)據(jù)庫社招之WHERE優(yōu)化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
mysql啟用skip-name-resolve模式時出現(xiàn)Warning的處理辦法
在優(yōu)化MYSQL配置時,加入 skip-name-resolve ,在重新啟動MYSQL時檢查啟動日志,發(fā)現(xiàn)有警告信息2012-07-07
MySQL 查找價格最高的圖書經(jīng)銷商的幾種SQL語句
不同的圖書,在不同的經(jīng)銷商的價格不同,我們這里要找到每種圖書最高的經(jīng)銷商是誰? 找最低的類似了。2009-07-07
MySQL中的LENGTH()函數(shù)用法詳解與實例分析
MySQL LENGTH()函數(shù)用于計算字符串的字節(jié)長度,區(qū)別于CHAR_LENGTH()的字符長度,適用于多字節(jié)字符集(如UTF-8)的數(shù)據(jù)驗證、截取及遷移優(yōu)化,需注意NULL和編碼影響,本文給大家介紹MySQL中的LENGTH()函數(shù)用法詳解與實例分析,感興趣的朋友一起看看吧2025-07-07
MySQL學習第三天 Windows 64位操作系統(tǒng)下驗證MySQL
MySQL學習第三天教大家如何在Windows 64位操作系統(tǒng)下驗證MySQL,感興趣的小伙伴們可以參考一下2016-05-05
Mysql學習之創(chuàng)建和操作數(shù)據(jù)庫及表DDL大全小白篇
本篇文章是MySQL小白入門篇,主要講解創(chuàng)建和操縱數(shù)據(jù)庫及表懂得了,內(nèi)容非常全面,有需要的朋友可以借鑒參考下,希望可以有所幫助2021-09-09
解決mysql啟動報錯:The server quit without upda
這篇文章總結了多種MySQL報錯的可能原因和解決方法,從依賴文件缺失到配置文件錯誤,再到權限問題和SELinux設置等,涵蓋了多種常見問題及其解決步驟2024-12-12

