JSON_EXTRACT比字符串匹配快得多,因MySQL将JSON存为带偏移索引的紧凑二进制格式,可直接定位字段值内存位置,避免全文扫描或正则解析。

JSON_EXTRACT 为什么比字符串匹配快得多
因为 JSON_EXTRACT 直接操作二进制 JSON 内部结构,不依赖全文扫描或正则解析。MySQL 8.0 把 JSON 存成带偏移索引的紧凑二进制格式,JSON_EXTRACT(data, '$.price') 能跳过整个文档其余部分,直接定位到 price 字段值所在内存位置——这和从 VARCHAR 里用 SUBSTRING_INDEX 或正则硬扒有数量级差异。
别直接在 WHERE 里裸用 JSON_EXTRACT
写 WHERE JSON_EXTRACT(data, '$.status') = 'completed' 看似合理,但会触发全表扫描:优化器无法利用索引加速这个表达式。容易踩的坑包括:
- 没建生成列就指望它走索引
- 路径写错(比如漏掉
$.或用单引号包裹路径)导致返回 NULL,查不到数据还无报错 - 对 JSON 数组用
$.tags[0]查询时,数组为空或越界也返回 NULL,条件失效
正确做法是配合虚拟生成列 + 普通索引,例如:
ALTER TABLE orders ADD COLUMN status VARCHAR(20) AS (JSON_UNQUOTE(JSON_EXTRACT(data, '$.status'))) STORED; CREATE INDEX idx_status ON orders(status);
-> 和 ->> 的区别必须分清
-> 是 JSON_EXTRACT 的简写,返回带双引号的 JSON 字符串;->> 等价于 JSON_UNQUOTE(JSON_EXTRACT(...)),返回干净的字符串或数字。常见误用:
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
- 用
data->'$.price' > 10—— 实际比较的是字符串"25.0"和10,结果不可靠 - 用
data->>'$.price' > 10—— 正确,MySQL 会自动转为 DECIMAL 比较 - 对布尔值用
->得到true(小写无引号),但它是 JSON 布尔类型,不能直接参与= true判断;要用->>或JSON_CONTAINS
多值索引只对 JSON 数组有效,且需 MySQL 8.0.17+
想查 "labels": ["fresh", "sweet"] 里是否含 "sweet",不能只建普通索引。必须用多值索引:
CREATE INDEX idx_labels ON orders (data->>"$.labels");
注意两点:
- 路径后必须用
->>,不能用->或JSON_EXTRACT - 只能用于
JSON_CONTAINS、MEMBER OF这类函数,不能用于=或IN
真正容易被忽略的是:多值索引不加速 JSON_LENGTH 或 JSON_KEYS 类函数,也不支持嵌套数组路径如 $.items[*].price —— 那些仍得靠生成列拆解。

















