MySQL JSON查询与索引详解
作者:愤怒的苹果ext
本文给大家介绍了MySQL JSON查询与索引的相关知识,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
前言
- 自MySQL 5.7.8开始引入原生JSON支持,可用于存储动态的列。此时如果想要建立索引,要先建立JSON某一列的
虚拟列,使用虚拟列查询。从MySQL 8.0.17开始,InnoDB支持多值索引,相比老版本的查询方式就更直接了。
准备
- 创建一张配置表,建表语句如下。
CREATE TABLE `t_config` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键', `extras` json DEFAULT NULL COMMENT '扩展列json字段', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='配置表';
- 测试数据
INSERT INTO `t_config` (`id`, `extras`) VALUES (1, '{\"color\": \"red\", \"phone\": [\"157\", \"153\"]}');
INSERT INTO `t_config` (`id`, `extras`) VALUES (2, '{\"color\": \"green\", \"phone\": [\"157\", \"154\"]}');
- 下面就开始介绍
虚拟列和多值索引查询与索引方式。
虚拟列
测试平台5.7.26

查询
SELECT * FROM `t_config` WHERE extras->'$.color' = 'red'; 或 SELECT * FROM `t_config` WHERE json_contains(extras->'$.color','"red"');

现在是走全表扫描

下面创建虚拟列和索引
ALTER TABLE `t_config` ADD COLUMN `v_color` VARCHAR(32) GENERATED ALWAYS AS (JSON_UNQUOTE(JSON_EXTRACT(`extras`, _utf8mb4'$.color'))) VIRTUAL NULL; CREATE INDEX idx_v_color on t_config(v_color);
查询就能走索引了
EXPLAIN SELECT * FROM `t_config` WHERE v_color = 'red';

但是数组phone未找到合适的方式查询。
多值索引
测试平台8.0.43

查询(第二条语句不能利用索引)
SELECT * FROM `t_config` WHERE json_contains(extras->'$.color','"red"'); 或者 SELECT * FROM `t_config` WHERE extras->'$.color' = 'red';

当前是全表扫描
EXPLAIN SELECT * FROM `t_config` WHERE json_contains(extras->'$.color','"red"');

增加json里 color字段索引
alter table t_config add index json_color( (cast(extras->'$.color' as char(32) array)));
现在就能走索引了

- 对于数字数组字段,查询方式
- 要先创建索引,才能查到数据
alter table t_config add index phone( (cast(extras->'$.phone' as unsigned array)) );
-- 查询phone字段
SELECT * FROM `t_config` WHERE json_contains(extras->'$.phone' , '157');
-- 查询phone字段, 参数数组
SELECT * FROM `t_config` WHERE json_contains(extras->'$.phone' , CAST('[157,153]' AS JSON));
能走索引

总结
- 从执行计划看,虚拟列的索引执行计划更优,但利用多值索引的
json_contains查询方式就不需要转换SQL。 - 数组列:虚拟列暂未找到查询数组的方式。多值索引要先创建才能查到数据。
参考
到此这篇关于MySQL JSON查询与索引的文章就介绍到这了,更多相关mysql json索引内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
