資料表 `line_sid` 字段已建立索引,執行查詢時 `EXPLAIN` 顯示 `Using filesort`,且資料量僅 9000 條,理應走索引排序。
經排查,該字段在建表時被定義為 `DECIMAL` 類型,而查詢條件或關聯條件中傳入的參數為整數或字符串,導致 MySQL 發生隱式類型轉換,使索引失效,被迫使用文件排序。
-- 建表示例
CREATE TABLE t_log (
id INT PRIMARY KEY,
line_sid DECIMAL(20,0), -- 此處為 Decimal 類型
INDEX idx_line_sid (line_sid)
);
-- 查詢時傳入整數
EXPLAIN SELECT * FROM t_log WHERE line_sid = 12345; -- 可能出現 Using filesort
ALTER TABLE t_log MODIFY line_sid BIGINT;
SELECT * FROM t_log WHERE line_sid = CAST(12345 AS DECIMAL(20,0));
MySQL 在比較不同類型時,會將字符串/整數轉換為數值類型進行比較。當列類型為 `DECIMAL` 而參數為整數時,MySQL 可能選擇將列值轉換為雙精度浮點數,導致無法使用索引。這在《MySQL 高性能》中稱為「隱式轉換導致索引失效」的經典案例。
修改字段類型後,同樣查詢不再出現 `Using filesort`,性能顯著提升。