JSON_CONTAINS 可查数组中任意值匹配,但需确保类型一致并用合法JSON格式传参,如CAST(123 AS JSON);多值OR查询推荐JSON_OVERLAPS;函数索引需与查询表达式完全一致才能加速。
JSON_CONTAINS 能否查出数组中任意一个值匹配?
可以,但必须注意 JSON_CONTAINS 默认是「全匹配」语义:它检查的是整个 JSON 值是否包含指定子文档,不是简单的“数组里有没有这个元素”。想查数组中是否存在某个值,得把目标值也包装成 JSON 格式传进去。
- 错误写法:
JSON_CONTAINS(json_col, '123')—— 字符串'123'不是合法 JSON,MySQL 会静默转为"123"(带引号),导致匹配失败 - 正确写法:
JSON_CONTAINS(json_col, '"123"')或JSON_CONTAINS(json_col, CAST(123 AS JSON)) - 若字段存的是整数数组
[1,2,123,4],用'"123"'匹配不到,必须用'123'(不带引号)——但此时要确保传入的是合法 JSON 数字字面量,推荐用CAST(123 AS JSON)
如何高效查询 JSON 数组里的多个值(OR 逻辑)?
MySQL 原生不支持 JSON_CONTAINS 的多值 OR 查询(比如“数组里有 100 或 200 或 300”),必须拆成多个 OR 条件,或改用 JSON_OVERLAPS(8.0.17+)。
-
JSON_OVERLAPS更直观:JSON_OVERLAPS(json_col, CAST('[100,200,300]' AS JSON))—— 只要两个数组有交集就返回 true - 低版本只能手写:
JSON_CONTAINS(json_col, CAST(100 AS JSON)) OR JSON_CONTAINS(json_col, CAST(200 AS JSON)) OR ... - 注意性能:每个
JSON_CONTAINS都会触发完整 JSON 解析,字段无索引时大数据量下很慢
给 JSON 数组字段加索引为什么不起作用?
直接在 JSON 字段上建普通索引(INDEX(json_col))对 JSON_CONTAINS 查询无效。MySQL 要求必须建「函数索引」,且索引表达式需和查询条件完全一致。