索引建立後能否生效取決於查詢寫法與設計模式。本文彙總 7 大實戰優化策略,涵蓋查詢改寫、複合索引設計、覆蓋索引、排序優化、鎖優化與維護工具。
-- ❌ 失效
SELECT * FROM users WHERE UPPER(name) = 'ABC';
-- ✅ 生效
SELECT * FROM users WHERE name = 'ABC';
原則:索引欄位保持「乾淨」,所有轉換移至常數側。
COUNT(DISTINCT col) / COUNT(*),越接近 1 越好INDEX idx_name (name(10))遵循最左前綴原則:INDEX (a,b,c) 支援 a, a,b, a,b,c 查詢。
定義: 索引葉節點已包含查詢所需所有欄位,無需回叢集索引查完整行。
-- 索引
INDEX idx_order (user_id, status, created_at)
-- 查詢可走覆蓋索引
SELECT user_id, status, created_at FROM orders WHERE user_id = 123;
優勢: 減少隨機 I/O → 順序掃描索引、避免 InnoDB 雙重查詢、減少 MyISAM 系統呼叫。
失效場景: SELECT *、雙 % LIKE、引擎不支援。
條件:
ORDER BY 完全一致ORDER BY 欄位全屬關聯查詢的第一張表 (驅動表)| 類型 | 範例 | 處理 |
|---|---|---|
| 重複索引 | PK(id), UNIQUE(id), INDEX(id) | 保留 PK,刪除其餘 |
| 冗餘索引 | INDEX(a), INDEX(a,b) | 刪除 INDEX(a) |
工具檢測:pt-duplicate-key-checker -h localhost
-- 更新統計資訊 (優化器決策依據)
ANALYZE TABLE table_name;
-- 整理碎片 (InnoDB 重建表)
OPTIMIZE TABLE table_name;
-- 或
ALTER TABLE table_name ENGINE=InnoDB;
-- 5.7+ performance_schema
SELECT * FROM sys.schema_unused_indexes;