查詢優化非單點技巧,而是「建立索引 → 分析執行計劃 → 調整內部參數」的系統工程。本文以實戰案例演示從全表掃描到索引覆蓋的完整優化路徑,並總結關鍵內部參數調優方向。
建立索引**:
CREATE INDEX idx_username ON users(username);
驗證索引**:
SHOW INDEX FROM users;
-- 關鍵欄位:Key_name, Column_name, Cardinality (基數), Index_type (BTREE)
索引設計鐵律**:
(a,b,c) 支援 a/a,b/a,b,c 查詢SELECT a,b FROM t WHERE c=1 → 索引 (c,a,b) 避免回表實戰案例:四表關聯優化**
EXPLAIN SELECT city.name, city.district
FROM city, country
WHERE city.countrycode = country.code AND country.code = 'IND';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE country const PRIMARY PRIMARY 3 const 1 Using index
1 SIMPLE city ALL NULL NULL NULL NULL 4079 Using where
city 表 type=ALL,掃描 4079 行,Using where 表示 Server 層過濾。
CREATE INDEX idx_countrycode ON city(countrycode);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE country const PRIMARY PRIMARY 3 const 1 Using index
1 SIMPLE city ref idx_countrycode idx_countrycode 3 const 333 Using where
city 表 type=ref,key=idx_countrycode,rows=333,**掃描行數降低 92%**。
| 參數 | 作用域 | 核心影響 | 調優方向 |
|---|---|---|---|
key_buffer_size | Global (MyISAM) | 索引塊緩衝區 | 專用 DB 設 25-30% 物理記憶體 |
innodb_buffer_pool_size | Global (InnoDB) | **核心緩衝池** (數據+索引+鎖+自適應雜湊) | **60-70% 物理記憶體,單一最重要參數** |
read_buffer_size | Session | 全表掃描順序讀取緩衝 | 大量範圍查詢適度調大 (1-8M) |
table_open_cache | Global | 表定義/結構緩存數量 | > max_connections × 平均單查詢表數 |
long_query_time | Global/Session | 慢查詢門檻 (秒) | 設 1 秒或更低,配合 log_queries_not_using_indexes |
sort_buffer_size | Session | ORDER BY/GROUP BY 排序緩衝 | 複雜排序調大 (2-16M),謹防 OOM |
join_buffer_size | Session | 無索引關聯緩衝 | 優化 SQL 以用索引關聯,而非調大此參數 |
SHOW PROCESSLIST、應用層 APM 告警EXPLAIN、SHOW INDEX、OPTIMIZE TABLE 更新統計pt-query-digest 對比、生產灰度my.cnf、索引變更納入變更管理、文檔更新EXPLAIN FORMAT=JSON (5.6+):輸出詳細成本估算、查詢改寫資訊EXPLAIN ANALYZE (8.0.18+):**實際執行**並輸出真實行數、耗時、迴圈次數,**優化驗證神器**OPTIMIZER_TRACE:追蹤優化器決策過程,排查為何不走預期索引ANALYZE TABLE ... UPDATE HISTOGRAM (8.0+):非索引欄位選擇性估算掌握「索引建模 → EXPLAIN 診斷 → 參數調校」三板斧,並建立「慢查詢發現 → 分析優化 → 驗證固化」閉環,是 MySQL DBA 與後端工程師的核心硬技能。