导读:本期聚焦于小伙伴创作的《mysql如何为JSON字段创建索引_使用8.0函数索引优化查询性能》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《mysql如何为JSON字段创建索引_使用8.0函数索引优化查询性能》有用,将其分享出去将是对创作者最好的鼓励。

mysql 8.0版本新增的函数索引特性,支持对JSON字段中的具体路径值创建索引,从而大幅提升涉及JSON字段的查询性能。传统方式中直接对JSON字段建普通索引无法生效,函数索引则通过提取JSON路径的标量值来构建索引结构,完美解决了这一痛点。

JSON字段索引的痛点

JSON类型字段在mysql中存储的是非结构化数据,普通B树索引无法直接对JSON整体内容生效。如果业务中经常需要根据JSON字段内部的某个属性查询数据,比如用户表的扩展信息字段ext_info中存储了用户的城市编码,查询某个城市的所有用户时,全表扫描会导致性能严重下降。

mysql 8.0函数索引原理

函数索引允许对表达式的计算结果创建索引,针对JSON字段,我们可以通过JSON_EXTRACT函数提取指定路径的标量值,再基于这个提取结果创建索引。mysql会将函数表达式的计算结果持久化到索引中,查询时如果匹配到相同的表达式,就可以直接走索引查询,避免全表扫描。

支持的JSON提取函数

  • JSON_EXTRACT(json_doc, path):提取JSON文档中指定路径的值,返回JSON类型结果
  • ->JSON_EXTRACT的简写形式,比如ext_info->'$.city_code'
  • ->>:提取后返回字符串类型,等价于JSON_UNQUOTE(JSON_EXTRACT(...))

创建JSON字段函数索引步骤

1. 准备测试表结构

首先创建一个包含JSON字段的用户表,插入测试数据:

-- 创建用户表,ext_info为JSON类型字段
CREATE TABLE user_info (
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50) NOT NULL,
    ext_info JSON
);

-- 插入测试数据
INSERT INTO user_info (username, ext_info) VALUES
('张三', '{"city_code": "110100", "age": 25}'),
('李四', '{"city_code": "310100", "age": 30}'),
('王五', '{"city_code": "110100", "age": 28}'),
('赵六', '{"city_code": "440100", "age": 35}');

2. 创建函数索引

假设我们需要频繁查询ext_infocity_code为某个值的所有用户,就可以为JSON_EXTRACT(ext_info, '$.city_code')创建函数索引:

-- 为JSON字段的city_code路径创建函数索引
CREATE INDEX idx_ext_info_city_code 
ON user_info ((JSON_EXTRACT(ext_info, '$.city_code')));

也可以使用->简写形式创建,效果完全一致:

CREATE INDEX idx_ext_info_city_code 
ON user_info ((ext_info->'$.city_code'));

3. 验证索引生效情况

使用EXPLAIN语句分析查询计划,查看索引是否被使用:

-- 查询北京的用户,查看执行计划
EXPLAIN SELECT * FROM user_info 
WHERE JSON_EXTRACT(ext_info, '$.city_code') = '110100';

执行结果中如果key列显示idx_ext_info_city_code,说明索引已经生效。如果使用->>提取字符串值查询,需要对应创建匹配的函数索引:

-- 创建返回字符串类型的函数索引
CREATE INDEX idx_ext_info_city_code_str 
ON user_info ((ext_info->>'$.city_code'));

-- 该查询会使用上面的索引
EXPLAIN SELECT * FROM user_info 
WHERE ext_info->>'$.city_code' = '110100';

注意事项

  • 函数索引的表达式必须和查询中的表达式完全一致才会生效,比如创建的是JSON_EXTRACT索引,查询时用->>可能无法匹配索引
  • 函数索引会占用额外的存储空间,需要根据实际查询频率权衡是否创建
  • mysql 5.7版本不支持函数索引,只能使用虚拟列的方式间接为JSON字段创建索引,8.0版本的函数索引是更简洁的方案
  • 如果JSON路径不存在对应值,提取结果为NULL,NULL值不会存入普通索引,因此查询NULL值无法使用该函数索引

虚拟列方案对比(兼容低版本)

如果是mysql 5.7版本,可以通过添加虚拟列再建索引的方式实现类似效果:

-- 添加虚拟列,提取city_code
ALTER TABLE user_info 
ADD COLUMN city_code VARCHAR(20) 
GENERATED ALWAYS AS (ext_info->>'$.city_code') VIRTUAL;

-- 为虚拟列创建索引
CREATE INDEX idx_city_code ON user_info (city_code);

-- 查询时使用虚拟列即可走索引
SELECT * FROM user_info WHERE city_code = '110100';

这种方式相比8.0的函数索引步骤更繁琐,且会修改表结构,优先推荐使用8.0的函数索引方案。

mysqlJSON字段函数索引查询优化数据库索引修改时间:2026-07-02 17:21:41

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。