CREATE TABLE `foo` (
`key` VARCHAR(10) NOT NULL,
`time` INT(11) NOT NULL,
PRIMARY KEY (`key`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
插入 30 萬筆測試資料。
| SQL | 耗時 | EXPLAIN 型別 |
|---|---|---|
SELECT * FROM foo WHERE `key` = 1293322797 | 0.1288 秒 | ALL(全表掃描) |
SELECT * FROM foo WHERE `key` = '1293322797' | 0.0009 秒 | const(主鍵查找) |
效能差距:約 140 倍!
key 與數值 1293322797 比較,觸發**隱式轉型**,將 key 每行轉為數值再比較,**導致索引失效**,只能全表掃描。-- 同樣慢:全表掃描
SELECT * FROM foo WHERE `key` > 1293322797;
-- 同樣快:走索引
SELECT * FROM foo WHERE `key` > '1293322797';
sql_mode=STRICT_ALL_TABLES 等嚴格模式,盡早發現型別不匹配。MySQL 型別轉換規則:字串與數值比較時,字串轉數值。'abc' = 0 為真。這意味著 WHERE varchar_col = 123 等同於 WHERE CAST(varchar_col AS UNSIGNED) = 123,函數作用在欄位上直接導致索引失效(Index Condition Pushdown 也無法生效)。