给同一个VARCHAR索引列分别用字符串和数字字面量做查询条件,看隐式类型转换真实是怎么把一次索引查找降级成全索引扫描的。
代码CREATE TABLE str_idx (id INT PRIMARY KEY, code VARCHAR(20)); CREATE INDEX idx_code ON str_idx(code); SELECT * FROM str_idx WHERE code = '1001'; -- 字符串字面量,类型匹配 SELECT * FROM str_idx WHERE code = 1001; -- 数字字面量,触发隐式转换
WHERE code = '1001': -> Covering index lookup on str_idx using idx_code (code = '1001') (cost=0.35 rows=1)
字符串字面量和VARCHAR列的类型真实完全匹配,MySQL能直接拿'1001'去idx_code这棵索引树上做一次精确查找,真实估算只要扫1行、代价0.35。
WHERE code = 1001:
-> Filter: (str_idx.`code` = 1001) (cost=101 rows=100)
-> Covering index scan on str_idx using idx_code (cost=101 rows=1003) ← 真实扫了全部1003行每一步都是本文上面用EXPLAIN FORMAT=TREE跑出来的原始结果。
EXPLAIN FORMAT=TREE:区分Index lookup和Index scan+Filter