mysql 8.0 的 json_extract 平均快 15%–35%,主要因原生解析器替代 boost.propertytree、减少内存拷贝;但优势依赖 not null 定义、无通配符路径、innodb_strict_mode=on,且需配合生成列+索引才能体现真实性能提升。

MySQL 8.0 的 JSON_EXTRACT 确实比 5.7 快,但快多少取决于数据结构和索引使用情况
直接结论:在同等硬件、相同 JSON 数据结构、未建虚拟列索引的前提下,MySQL 8.0 的 JSON_EXTRACT 平均快 15%–35%,主要受益于内部 JSON 解析器重构(从 Boost.PropertyTree 换成原生 parser)和更少的内存拷贝。但这个“快”有前提——如果查询没走索引或 JSON 嵌套过深,两者都会明显变慢,8.0 的优势会被掩盖。
测试时必须控制这 3 个变量,否则对比无效
很多人测出“8.0 更慢”,其实是没控参。关键干扰项:
-
JSON字段是否为NOT NULL:5.7 对 NULL JSON 处理有额外空值检查开销,8.0 优化了这部分,但若字段定义含NULL,差异会缩小 - 路径表达式是否带通配符(如
$[*].name):5.7 不支持数组通配符展开,会退化为全量解析;8.0 支持且做了短路优化,此时差距可拉到 3× 以上 - 是否启用
innodb_strict_mode=ON:5.7 默认关,松散模式下 JSON 校验延迟到首次访问;8.0 默认开,校验前置——这会让 8.0 首次写入略慢,但后续读取更稳定
真实场景中,8.0 的性能优势常被 JSON 字段无索引抵消
即使函数本身更快,如果查询条件是 WHERE JSON_EXTRACT(data, '$.status') = 'active',而 data 没建生成列+索引,MySQL 就得对每行做完整 JSON 解析——这时版本差异几乎不可测,瓶颈在 I/O 和解析,不在函数实现。
详细的 Three.js 3D 图形参考,涵盖场景设置、相机、几何体、材质、光照、动画、控制器、加载器、数学工具和调试。
正确做法(仅 8.0 支持):
- 用
ALTER TABLE t ADD COLUMN status VARCHAR(20) AS (JSON_UNQUOTE(JSON_EXTRACT(data, '$.status'))) STORED - 再
CREATE INDEX idx_status ON t(status) - 5.7 只能靠冗余字段或触发器模拟,维护成本高且易不同步
别忽略字符集与排序规则对 JSON 路径匹配的影响
JSON_EXTRACT 返回的是 JSON 类型值(非字符串),但比较时隐式转为字符串。若字段用 utf8mb4_0900_as_cs(8.0 默认),大小写敏感;而 5.7 常用 utf8mb4_general_ci,会忽略大小写。这意味着:
- 同一条语句
JSON_EXTRACT(data, '$.Name') = '"Admin"'在 5.7 可能命中"name": "admin",在 8.0 默认不命中 - 若没意识到这点,测试时可能误判 8.0 “结果不对”,进而怀疑性能数据
- 建议统一用
COLLATE utf8mb4_bin显式指定比较行为,避免隐式转换干扰基准
真正影响性能的,往往不是函数本身,而是你有没有把 JSON 当成“需要索引的字段”来设计,而不是当成“存完就不管的 blob”。










