索引是排序後的資料結構(B+ Tree),將無序表變為有序存取路徑。MyISAM 索引檔與資料檔分離,InnoDB 聚簇索引將資料與主鍵同頁儲存。
MIN/MAX 直接走索引極值ORDER BY/GROUP BY 消除 filesortSELECT indexed_col FROM tbl WHERE indexed_col > 10 僅讀索引不回表WHERE、JOIN ON、ORDER BY、GROUP BY 的欄位INDEX idx_name (name(10)),平衡選擇度與空間INDEX (a,b,c) 支援 a、a,b、a,b,c,不支援 b、c、b,c=、>、>=、<、<=、BETWEEN、IN、LIKE 'prefix%'-- 1. 分析查詢計畫
EXPLAIN SELECT * FROM tbl WHERE col = 1;
-- 關鍵欄位:
-- type: ALL(全掃) > index > range > ref > eq_ref > const > system
-- key: 實際使用索引
-- rows: 預估掃描列數
-- Extra: Using index(覆蓋)、Using where、Using temporary、Using filesort
-- 2. 更新統計資訊
ANALYZE TABLE tbl; -- MyISAM/InnoDB
-- 3. 強制連接順序
SELECT * FROM tbl1 STRAIGHT_JOIN tbl2 ON ...;
-- 4. 慢查詢日誌分析
mysqldumpslow -s t /var/log/mysql/slow.log
| 限制 | 繞過方案 |
|---|---|
| 隱式型別轉換導致索引失效 | 欄位與參數型別嚴格一致,避免 VARCHAR vs INT |
| 函數/運算在索引欄上 | 移至右側:WHERE date_col = DATE_SUB(NOW(), INTERVAL 1 DAY) |
LIKE '%keyword%' 導掃 | 全文索引、Elasticsearch、前綴匹配 LIKE 'keyword%' |
OR/IN 可能走臨時表 | 拆分為 UNION ALL、或確保各條件有獨立索引 |
EXPLAIN 確認 type 非 ALL、key 非 NULLrows 預估是否合理(遠大於實際回傳可能統計過期)SELECT *,僅查詢所需欄位