文章目錄
- "為什么訂單查詢突然變慢了?"——從這個問題開始說起
- 一、索引的生死時速(必考題!)
- 二、事務的"套娃"藝術
- 三、鎖機制的相愛相殺
- 四、存儲引擎的抉擇
- 五、慢查詢的破案技巧
- 六、分頁的深度優化
- 七、高可用架構的基石
- 八、性能調優的終極武器
- 最后的大實話
“為什么訂單查詢突然變慢了?”——從這個問題開始說起
上周幫學弟復盤面試時,他提到最怕遇到這種開放性問題:“我們的訂單表查詢突然變慢,可能是什么原因?該怎么優化?”(面試官超愛這種場景題!!!)今天我們就以這個典型問題為引子,拆解MySQL必考的8大核心知識點。
一、索引的生死時速(必考題!)
面試官連環問:
- 你建的索引為什么失效了?
- 什么情況下索引會失效?
- 如何查看SQL的執行計劃?
高頻翻車場景:
-- 致命陷阱1:隱式類型轉換
SELECT * FROM orders WHERE order_no = 10086; -- order_no是varchar類型-- 致命陷阱2:左模糊查詢
SELECT * FROM orders WHERE product_name LIKE '%手機%';-- 致命陷阱3:對索引列使用函數
SELECT * FROM orders WHERE DATE(create_time) = '2023-08-15';
避坑指南(劃重點):
- 使用
EXPLAIN
查看執行計劃時,重點看type
列(ALL全表掃描要警惕) - 字符串字段查詢值必須加引號
- 聯合索引注意最左前綴原則(比如index(a,b,c) 只查b,c用不上索引)
二、事務的"套娃"藝術
靈魂四連問:
- ACID特性分別怎么實現的?
- 事務隔離級別有哪些?(附贈連環追問)
- MVCC機制了解嗎?
- 什么是幻讀?怎么解決的?
隔離級別對照表(建議背下來):
隔離級別 | 臟讀 | 不可重復讀 | 幻讀 |
---|---|---|---|
READ UNCOMMITTED | ?? | ?? | ?? |
READ COMMITTED | ?? | ?? | ?? |
REPEATABLE READ | ?? | ?? | ?? |
SERIALIZABLE | ?? | ?? | ?? |
實戰建議:
- MySQL默認使用RR級別但通過Next-Key Locking解決幻讀
- 開發中慎用
SELECT ... FOR UPDATE
(容易引發死鎖)
三、鎖機制的相愛相殺
死亡問題:
“你說說樂觀鎖和悲觀鎖的區別?我們系統該用哪種?”
場景化解析:
- 庫存扣減場景:版本號樂觀鎖(update set stock=stock-1, version=version+1 where version=當前版本)
- 財務記賬場景:悲觀鎖(先select for update再操作)
鎖的進化史:
- 表級鎖(MyISAM的痛)
- 行級鎖(InnoDB的救贖)
- 間隙鎖(解決幻讀的神器)
- 意向鎖(提高鎖檢測效率)
四、存儲引擎的抉擇
必問題:“為什么InnoDB比MyISAM更適合現代應用?”
對比清單:
- 事務支持:InnoDB? vs MyISAM?
- 崩潰恢復:InnoDB有redo log
- 并發性能:InnoDB行級鎖 vs MyISAM表鎖
- 全文索引:MyISAM?(但5.6+版本InnoDB也支持了)
冷知識:
- 系統表空間文件
ibdata1
會像滾雪球一樣增大(記得配置自動擴展)
五、慢查詢的破案技巧
排查四部曲:
- 開啟慢查詢日志
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 2; -- 單位秒
- 使用
mysqldumpslow
分析日志 - 用
SHOW PROCESSLIST
查看實時查詢 - 性能分析神器:
pt-query-digest
六、分頁的深度優化
經典問題:
“為什么LIMIT 100000,10這么慢?怎么優化?”
優化方案對比:
-- 原始寫法(性能殺手)
SELECT * FROM orders LIMIT 100000,10;-- 優化方案1:子查詢法
SELECT * FROM orders WHERE id >=
(SELECT id FROM orders ORDER BY id LIMIT 100000,1) LIMIT 10;-- 優化方案2:游標分頁(適合連續翻頁)
SELECT * FROM orders WHERE id > 100000 ORDER BY id LIMIT 10;
七、高可用架構的基石
連環追問:
- 主從復制原理?
- 讀寫分離要注意什么?
- 怎么保證數據一致性?
復制原理圖解:
主庫binlog -> 從庫IO線程 -> relay log -> SQL線程重放
避坑指南:
- 主從延遲問題(show slave status查看Seconds_Behind_Master)
- 半同步復制配置(等至少一個從庫確認)
- GTID復制模式(5.6+版本推薦)
八、性能調優的終極武器
調優三板斧:
- 參數調優:
# 內存相關
innodb_buffer_pool_size = 機器內存的70%
sort_buffer_size = 2M
join_buffer_size = 2M# 日志相關
sync_binlog = 1
innodb_flush_log_at_trx_commit = 1
- SQL優化(重中之重!)
- 架構優化(分庫分表、緩存策略等)
最后的大實話
每次面試到最后,面試官總會問:“你有什么問題要問我嗎?”(超級重要!!!)這時候可以問:
- 咱們業務當前遇到的最大數據庫挑戰是什么?
- 現在數據庫的QPS和主要瓶頸在哪里?
- 有沒有遇到過分庫分表的場景?
記住,MySQL面試就像醫生問診,要能快速定位問題,給出合理的解決方案。紙上得來終覺淺,建議大家在本地用Docker起個MySQL環境,把上述場景都實操一遍(真的會有新發現!)。最后祝大家面試時都能像操作EXPLAIN一樣,把面試官的問題看得透透的!