JSON_SEARCH() 返回 NULL 的主因是参数非法:json_doc 为空或非 JSON、search_str 含通配符未设 escape_char、one_or_all 大小写错误、路径越界;不区分大小写需用 LOWER() 包裹字段和搜索值,但会破坏结构;查不到时应先验证 JSON 合法性、值存在性及最简路径有效性;该函数不走索引且匹配不区分数据类型,精度低、性能差。

直接用 JSON_SEARCH() 查路径,但必须注意大小写、通配符和空值陷阱,否则返回 NULL 或空结果不是没匹配到,而是参数写错了。
为什么 JSON_SEARCH() 返回 NULL 而不是路径?
常见原因不是数据里没有目标字符串,而是参数不合法:
-
json_doc是NULL或非法 JSON(比如空字符串'')→ 函数直接返回NULL,不报错也不提示 -
search_str里含%或_,又没设escape_char→ 被当成 LIKE 模式匹配,可能误判或漏匹配 -
one_or_all写成'ONE'或'One'→ 必须小写'one'或'all',否则报错Invalid argument for JSON_SEARCH - 指定的
path不存在(如'$.tags[5]'但数组只有 3 个元素)→ 返回NULL
区分大小写的搜索怎么写才有效?
MySQL 默认区分大小写,JSON_SEARCH() 本身不提供 IGNORE CASE 参数。想实现不区分大小写,得绕一下:
- 用
LOWER()包裹整个 JSON 字段再搜:JSON_SEARCH(LOWER(json_col), 'one', LOWER('VALUE')) - 但注意:这会破坏原始 JSON 结构(变成全小写字符串),仅适用于纯文本值搜索,不能用于带嵌套结构的路径定位
- 更稳妥的做法是:在应用层统一存小写值,或建生成列
GENERATED ALWAYS AS (LOWER(JSON_EXTRACT(json_col, '$.name'))) STORED加索引
查不到路径时,先用这些语句快速验证数据状态
别急着改 SQL,先确认数据本身是否合规:
- 检查字段是否为合法 JSON:
SELECT id, json_col, JSON_VALID(json_col) FROM table_name WHERE id IN (1,2,3);→ 返回0就说明这行根本不能搜 - 确认目标值真实存在且可提取:
SELECT JSON_EXTRACT(json_col, '$.name') FROM table_name WHERE id = 1;→ 看输出是不是你预期的字符串 - 测试最简路径是否生效:
SELECT JSON_SEARCH('{"name": "Alice"}', 'one', 'Alice');→ 应该返回"$.name",否则环境或版本有异常
性能和路径精度容易被忽略的点
JSON_SEARCH() 不走索引,全表扫描 JSON 内容,大数据量时很慢;而且它只返回字符串匹配路径,不校验数据类型:
- 搜
'true'可能命中布尔值true,也可能命中字符串"true"—— 两者在 JSON 中完全不同 - 搜
'123'可能匹配数字123、字符串"123"、甚至数组里的元素[123],结果不可控 - 如果只关心某个固定路径下的值,优先用
JSON_CONTAINS_PATH()+JSON_CONTAINS()组合,比盲搜更准更快


















