like查询返回空结果最常见原因是字段类型不匹配:如phone为int/bigint时,like '%123%'无法可靠匹配12345;应检查字段类型,改varchar或用cast(phone as char) like '%123%'。

LIKE查询返回空结果但数据明明存在
最常见原因是字段类型不匹配:比如phone是INT或BIGINT,而LIKE本质是字符串操作。MySQL会尝试隐式转换,但结果不可靠——尤其当值为纯数字时,LIKE '%123%'可能完全不匹配12345。
- 用
EXPLAIN确认是否走了索引;如果type是ALL,说明连索引都没用上,先别急着改SQL,先查字段类型 - 检查
DESCRIBE table_name,确认目标列类型;若为数字类型,要么改字段为VARCHAR,要么显式转成字符串:CAST(phone AS CHAR) LIKE '%123%' - CodeIgniter等ORM中调用
$this->db->like('phone', $key)时,框架默认不加CAST,需手动拼写原生条件或改用where+CAST
为什么EXPLAIN显示用了索引,但查询还是慢?
因为LIKE '%xxx%'哪怕有索引也白搭——B+树索引只支持最左前缀匹配,%开头等于放弃索引,优化器只能选全表扫描。
-
LIKE 'xxx%'能走索引;LIKE '%xxx'不能;LIKE '%xxx%'也不能 - MySQL 8.0+可用函数索引绕过:先建
ALTER TABLE t ADD INDEX idx_rev_col ((REVERSE(text_col))),再查WHERE REVERSE(text_col) LIKE REVERSE('%abc%') + '%' - 别信“加了索引就万事大吉”,
EXPLAIN里key字段非空≠真用了索引做高效查找;重点看type是否为range或ref,不是ALL
大小写、排序规则导致LIKE失效
不是所有数据库都忽略大小写。如果表用的是utf8mb4_0900_as_cs(区分大小写)或_bin排序规则,LIKE 'Error%'就匹配不到error开头的记录。
- 查当前列排序规则:
SHOW FULL COLUMNS FROM table_name WHERE Field = 'LogText',看Collation列 - 临时兼容写法:
WHERE LOWER(LogText) LIKE LOWER('%error%'),但注意这会让索引失效——除非你提前建了函数索引LOWER(LogText) - 更稳妥的做法是统一存小写,或在应用层归一化输入后再查
IN + LIKE组合根本就是逻辑错误
WHERE LogText IN ('%error%', '%fail%')不是模糊匹配,是精确匹配两个字面字符串——它只找内容刚好等于%error%的行,不是包含error的行。
- 正确写法只有两种:
LogText LIKE '%error%' OR LogText LIKE '%fail%',或用PATINDEX(SQL Server)、REGEXP(MySQL)、CONTAINS(全文索引)替代 - SQL Server 2016+可用
STRING_SPLIT动态展开关键词,避免硬编码多个OR - 别为了“简洁”牺牲语义——
IN和LIKE解决的是两类问题,强行混用只会查不到数据
LIKE '%...'这三个字符一出现,后面所有索引设计、联合索引、覆盖索引都自动作废。先确认业务是否真需要任意位置匹配,再决定是改查询逻辑、换索引类型,还是直接上全文检索。










