MySQL 根據統計資訊估算各執行計畫成本,選擇最低成本路徑。但統計資訊可能過時、不準確,導致次優計畫。
EXPLAIN SELECT * FROM t1 JOIN t2 ON t1.id = t2.id;
重點欄位:
type:system > const > eq_ref > ref > range > index > ALLkey:實際使用索引rows:預估掃描行數Extra:Using index、Using where、Using filesort、Using temporaryANALYZE TABLE t1, t2;
INFORMATION_SCHEMA.STATISTICS 中的基數。SET GLOBAL innodb_stats_persistent_sample_pages = 100 提高精度。-- 強制使用索引(優化器認為表掃描更貴時生效)
SELECT * FROM t1 FORCE INDEX (idx_col) JOIN t2 ON t1.col = t2.col;
-- 建議使用(優化器仍可選擇不採用)
SELECT * FROM t1 USE INDEX (idx_col) WHERE col > 100;
-- 忽略特定索引
SELECT * FROM t1 IGNORE INDEX (bad_idx) WHERE col = 'val';
| 變數 | 作用 | 建議值 |
|---|---|---|
max_seeks_for_key | 假設索引查找不超過 N 次,鼓勵用索引 | 1000 (預設 4294967295) |
optimizer_switch | 開關特定優化策略 | mrr=on,batched_key_access=off 等 |
eq_range_index_dive_limit | IN 列表超過 N 個值改用統計估算 | 200 (預設) |
EXPLAIN 確認是否 type=ALL、key=NULL、rows 偏大。ANALYZE TABLE 更新統計,再次 EXPLAIN。FORCE INDEX 驗證索引是否真能加速。max_seeks_for_key 或 optimizer_switch 微調。WHERE varchar_col = 123 導致索引失效,EXPLAIN 會顯示 Using where 而非 Using index condition。INDEX (a,b,c) 無法支援 WHERE b=1 或 WHERE a=1 AND c=2。