MySQL Hint 概述
類似 Oracle,MySQL 提供多種 Hint (提示) 讓開發者干預優化器行為,解決執行計劃不優、鎖衝突、緩存污染等問題。本文匯總常用 Hint 的語法、適用場景與注意事項。
索引控制類 Hint
| Hint | 語法 | 作用 | 適用場景 |
| FORCE INDEX | SELECT * FROM t FORCE INDEX (idx_name) ... | 強制使用指定索引,忽略其他索引 | 優化器誤選全表掃描或次優索引時 |
| IGNORE INDEX | SELECT * FROM t IGNORE INDEX (idx1, idx2) ... | 禁止使用指定索引 | 某索引導致效能劣化、統計信息不準時 |
| USE INDEX | SELECT * FROM t USE INDEX (idx_name) ... | 建議優化器使用指定索引 (可被忽略) | 輔助優化器決策,強制力弱於 FORCE |
查詢緩存控制
| Hint | 語法 | 說明 |
| SQL_NO_CACHE | SELECT SQL_NO_CACHE * FROM t ... | 不使用查詢緩存,不將結果存入緩存。適合實時性要求高、低頻執行的查詢 |
| SQL_CACHE | SELECT SQL_CACHE * FROM t ... | 顯式使用查詢緩存。需配合 query_cache_type=2 (DEMAND 模式) 生效 |
注意: MySQL 8.0 已移除查詢緩存功能,此類 Hint 僅適用 5.7 及以前版本。
執行優先級控制
| Hint | 適用語句 | 作用 | 典型場景 |
| HIGH_PRIORITY | SELECT, INSERT | 提高語句優先級,插隊執行 | 關鍵報表查詢、緊急數據寫入 |
| LOW_PRIORITY | INSERT, UPDATE, DELETE | 降低優先級,等待其他讀寫完成 | 批量導入、非即時數據同步 |
| DELAYED | INSERT, REPLACE | 客戶端立即返回 OK,數據進內存隊列異步寫入 | 日誌寫入、非關鍵數據收集 |
DELAYED 缺點: 無法獲取自增 ID,崩潰時隊列數據丟失。InnoDB 不支援,僅 MyISAM/MEMORY 有效。
連接順序與結果集處理
| Hint | 語法 | 作用 |
| STRAIGHT_JOIN | SELECT * FROM t1 STRAIGHT_JOIN t2 ON ... | 強制按 FROM 子句順序連接表 (t1 驅動 t2) |
| SQL_BUFFER_RESULT | SELECT SQL_BUFFER_RESULT * FROM t ... | 強制結果集存入臨時表,快速釋放表鎖,適合大結果集長時間傳輸 |
| SQL_BIG_RESULT | SELECT SQL_BIG_RESULT col, COUNT(*) FROM t GROUP BY col | 提示優化器結果集較大,使用磁盤臨時表並排序 |
| SQL_SMALL_RESULT | SELECT SQL_SMALL_RESULT ... | 提示結果集較小,優先使用內存臨時表 |
實戰組合範例
-- 場景:核心報表查詢,需強制使用覆蓋索引、跳過緩存、高優先級、大結果集緩衝
SELECT HIGH_PRIORITY SQL_NO_CACHE SQL_BUFFER_RESULT
u.id, u.name, COUNT(o.id) AS order_cnt
FROM `user` u
FORCE INDEX (idx_status_create_time)
STRAIGHT_JOIN `order` o
ON u.id = o.user_id
WHERE u.status = 1
AND o.create_time > '2024-01-01'
GROUP BY u.id, u.name
ORDER BY order_cnt DESC;
最佳實踐與避坑指南
- 慎用 FORCE INDEX: 優化器通常比人聰明,先用
EXPLAIN 分析,確認誤判才干預
- 統計信息為本: 定期
ANALYZE TABLE 更新統計信息,解決 90% 的誤選索引問題
- 版本兼容性: Hint 語法在版本間可能變化,升級前測試
- 不要過度優化: 過多 Hint 會綁死執行計劃,數據分布變化時反而拖累效能
- DEPRECATED 警示:
SQL_CACHE/NO_CACHE、DELAYED 在新版本已棄用/移除
查看優化器決策
EXPLAIN SELECT * FROM t FORCE INDEX (idx_a) WHERE a=1;
-- 輸出 key=idx_a 表示生效
-- possible_keys 顯示優化器原本考慮的索引