首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 效能優化全攻略:架構設計、索引策略與查詢重構實戰

     編輯:MySQL 資料庫相關知識

資料庫效能優化是系統工程,涵蓋架構設計、索引建模、SQL 重寫、參數調優、硬體資源規劃等多個維度。本文從表結構定義、索引優化、查詢改寫三大核心面向,提煉出經實戰驗證的優化法則與避坑指南。

一、表結構設計:從源頭減少效能債

欄位類型選擇鐵律

  1. 長度最小化:TINYINT 足夠時別用 INT,VARCHAR(20) 夠用別設 VARCHAR(255)
  2. 優先定長:頻繁更新的字串欄位考慮 CHAR 減少分頁分裂
  3. 盡量 NOT NULL:NULL 需額外位元組標記、複雜化索引統計、阻礙查詢優化器判斷
  4. 避免 ZEROFILL:數值型欄位前導補零屬應用層展示邏輯,非儲存邏輯
  5. 枚舉優於字串:已知有限值集(如狀態、性別)優先 ENUM 或 SET,儲存 1-2 字節 vs 字串長度

MySQL 常用類型儲存長度速查表

類型儲存長度備註
TINYINT1 字節-128~127 / 0~255
SMALLINT2 字節
MEDIUMINT3 字節
INT / INTEGER4 字節
BIGINT8 字節
FLOAT4 字節單精度
DOUBLE8 字節雙精度
DECIMAL(M,D)M+2 / D+2 字節精確小數,金融必用
DATE3 字節1000-01-01 ~ 9999-12-31
DATETIME8 字節不帶時區
TIMESTAMP4 字節1970-2038,帶時區轉換
CHAR(M)M 字節定長,右側空格填充
VARCHAR(M)實際長度+1/2 字節變長,<255 用 1 字節長度前綴
TEXT/BLOB實際長度+2 字節大物件,離頁儲存
ENUM1-2 字節取決於枚舉值數量
SET1-8 字節取決於成員數量

二、索引優化:查詢加速的核心槓桿

索引效能決定因子

  1. 欄位長度越短,索引越快:B+ 樹節點容納更多鍵值,樹高更低,I/O 更少
  2. 區分度越高(基數越大),索引越有效:性別欄位建索引幾乎無效,身分證號/手機號極佳
  3. 最左前綴原則:複合索引 (a,b,c) 支援 a、a,b、a,b,c 查詢,不支援 b、c、b,c

十大索引建模實戰法則

#場景索引策略原理
1GROUP BY 子句依欄位出現順序建複合索引避免 filesort,直接利用索引有序性
2DISTINCT 查詢依欄位出現順序建複合索引同 GROUP BY,利用索引去重
3WHERE 多個 AND 條件依條件出現順序建複合索引最左前綴匹配,單次索引掃描
4WHERE 多個 OR 條件對區分度最高欄位建單列索引OR 通常導致全表掃描,單列索引可用 index_merge
5內/外連接查詢對關聯欄位建索引驅動表關聯欄位有索引,被驅動表關聯欄位必須有索引
6主鍵額外加 UNIQUE勿重複建立主鍵本身已是唯一索引,多餘
7被索引欄位盡量 NOT NULLNULL 值統計複雜,可能導致優化器誤判
8寫入密集型表極度克制索引數量,避免複合/唯一索引每個索引都是寫入放大源頭
9覆蓋索引SELECT 欄位全包含在索引中避免回表,極大提升查詢速度
10前綴索引長字串取前 N 字元建索引INDEX idx_name(name(10)) 平衡空間與區分度

三、查詢語句優化:從執行計畫出發重構 SQL

EXPLAIN 是唯一真理

所有優化前後必須對比 EXPLAIN 輸出,重點關注:

  • type:system/const > eq_ref > ref > range > index > ALL(由好到壞)
  • key:實際使用的索引
  • rows:預估掃描行數(越小越好)
  • Extra:Using index(覆蓋索引)、Using where、Using temporary、Using filesort(需優化)

十大 SQL 改寫黃金法則

  1. 拒絕 SELECT *:只取業務必要欄位,減少網路傳輸、利用覆蓋索引、降低緩衝池壓力
  2. LIMIT 深分頁優化:LIMIT 1000000, 10 → 子查詢先取主鍵再回表:SELECT * FROM t WHERE id > (SELECT id FROM t LIMIT 1000000,1) LIMIT 10
  3. 函數下推至應用層:WHERE DATE(create_time) = '2024-01-01' → WHERE create_time >= '2024-01-01' AND create_time < '2024-01-02',保留索引可用性
  4. LIKE 避免前導萬用字元:%keyword 無法用索引,keyword% 可用
  5. 子查詢改 JOIN:MySQL 5.6+ 優化器改善,但複雜子查詢仍建議改寫為 INNER/LEFT JOIN 或 WITH CTE(8.0+)
  6. OR 拆分為 UNION:WHERE a=1 OR b=2 → SELECT * FROM t WHERE a=1 UNION SELECT * FROM t WHERE b=2,各走各的索引
  7. WHERE 條件順序匹配複合索引:INDEX(a,b,c) 對應 WHERE a=1 AND b=2 AND c=3
  8. 減少運算式複雜度:WHERE price * 1.1 > 100 → WHERE price > 100/1.1,使欄位單獨出現在運算子一側
  9. 大表分頁改游標/ID 續傳:前端改為「載入更多」模式,傳遞上次最大 ID
  10. 定期 ANALYZE TABLE:更新統計資訊,讓優化器做正確決策

四、進階優化方向

  • 分區表:按範圍/哈希/列表分區,實現分區裁剪,適用超大表(億級+)
  • 讀寫分離:主寫從讀,中間件(ProxySQL/ShardingSphere)路由
  • 分庫分表:水平拆分,解決單表寫入瓶頸與單庫連接數限制
  • 緩存層介入:Redis 熱點資料緩存,降低 DB QPS 壓力
  • 慢查詢日誌分析:long_query_time=1 + pt-query-digest 定期審視 Top N 慢查詢

總結

MySQL 優化無銀彈,唯有「正確的表結構 + 精準的索引 + 合理的 SQL + 持續的觀測」組合拳。建議建立優化閉環:慢查詢收集 → EXPLAIN 分析 → 索引/結構調整 → 效果驗證 → 固化規範,讓優化成為團隊基因而非個人英雄行為。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved