locate返回0表示关键词未找到;它非布尔函数,而是返回首次出现位置(从1起),需显式判断>0;仅mysql/mariadb支持,跨库需改用position、charindex等;默认不区分大小写,但受校对规则影响;无法利用b-tree索引,性能较差。

LOCATE 返回值为 0 表示关键词不存在
SQL 中 LOCATE 不是布尔函数,它返回关键词在字符串中首次出现的位置(从 1 开始计数),找不到时返回 0。所以不能直接用 WHERE LOCATE('abc', col) 判断存在性——因为当关键词出现在开头时,LOCATE 返回 1,而 1 在多数 SQL 引擎里会被当作真值;但若返回 0,就代表没找到。
正确写法是显式比较:
SELECT * FROM table_name WHERE LOCATE('keyword', column_name) > 0;
-
LOCATE('a', 'abc')→ 返回1 -
LOCATE('x', 'abc')→ 返回0 -
LOCATE('', col)在 MySQL 中返回1(空串总被视作在位置 1 匹配),需额外规避
MySQL 和 MariaDB 支持,PostgreSQL 和 SQL Server 不支持
LOCATE 是 MySQL/MariaDB 特有函数,PostgreSQL 要用 POSITION('str' IN col) 或 STRPOS(col, 'str'),SQL Server 得用 CHARINDEX('str', col)。三者都返回位置或 0(SQL Server 的 CHARINDEX 找不到时返回 0,行为一致)。
- MySQL:
LOCATE('foo', col) - PostgreSQL:
POSITION('foo' IN col) > 0或STRPOS(col, 'foo') > 0 - SQL Server:
CHARINDEX('foo', col) > 0 - SQLite:用
INSTR(col, 'foo') > 0
跨数据库写法不可行,必须按目标引擎选函数。
区分大小写取决于字段 collation 或数据库配置
LOCATE 默认不区分大小写,前提是字段的校对规则(collation)是 utf8mb4_general_ci 或类似 _ci 结尾的。如果字段用了 _bin 或 _cs(case-sensitive)校对,则 LOCATE('A', 'apple') 会返回 0。
- 查当前字段校对:执行
SHOW FULL COLUMNS FROM table_name LIKE 'column_name'; - 临时强制不区分:可用
LOWER(column_name)和LOWER('keyword')配合,但影响索引使用 - 想走索引又大小写无关?得建函数索引(MySQL 8.0+)或冗余小写字段
性能隐患:LOCATE 无法利用普通 B-tree 索引
哪怕字段上有索引,LOCATE('kw', column) 依然触发全表扫描——因为这是“模式内任意位置匹配”,优化器无法跳过索引树遍历。
- 前缀匹配(
column LIKE 'kw%')能用索引 - 后缀匹配(
column LIKE '%kw')和中缀匹配(LIKE '%kw%')都不能,LOCATE同理 - 高频模糊搜索建议改用全文索引(
MATCH ... AGAINST)或外部搜索引擎(如 Elasticsearch)
真正要查“是否包含”,且字段很长、数据量大时,别只图 LOCATE 写着顺手——先看执行计划 EXPLAIN,再决定要不要重构查询逻辑。










