MySQL JSON字段索引

数据库版本MySQL 8+支持对json类型字段进行索引,在之前的版本中,可以利用MySQL 5.7中的虚拟字段的功能来对JSON对象中的字段进行索引。

1.虚拟字段索引

1.创建虚拟列

虚拟列语法格式:

<type> [ GENERATED ALWAYS ] AS ( <expression> ) [ VIRTUAL|STORED ]
[ UNIQUE [KEY] ] [ [PRIMARY] KEY ] [ NOT NULL ] [ COMMENT <text> ]

在MySQL 5.7中,支持两种Generated Column,即Virtual Generated Column和Stored Generated Column,前者只将Generated Column保存在数据字典中(表的元数据),并不会将这一列数据持久化到磁盘上;后者会将Generated Column持久化到磁盘上,而不是每次读取的时候计算所得。很明显,后者存放了可以通过已有数据计算而得的数据,需要更多的磁盘空间,与Virtual Column相比并没有优势,因此,MySQL 5.7中,不指定Generated Column的类型,默认是Virtual Column。

如果需要Stored Generated Golumn的话,可能在Virtual Generated Column上建立索引更加合适,一般情况下,都使用Virtual Generated Column,这也是MySQL默认的方式

加完虚拟列的建表语句如下:

CREATE TABLE `table_name` (  
   `id` INT UNSIGNED NOT NULL,
   `business_attr` JSON NOT NULL,
   `attrs_virtual` VARCHAR(20) GENERATED ALWAYS AS (`business_attr` ->> '$.attrKey'), 
    -- 等效于 attrs_virtual` VARCHAR(20) GENERATED ALWAYS AS (json_extract(`business_attr` , '$.attrKey'))
   PRIMARY KEY (`id`)
);

2.虚拟列加索引

在刚刚加过的虚拟列上面加索引。

CREATE INDEX `index_attrs_key` ON `table_name`(`attrs_virtual`);  

3.查看执行计划

查看attrKey的值为‘1000’的记录的执行计划

explain SELECT * FROM table_name WHERE attrs_virtual='1000';

可以看到执行计划走了新建的索引。

2.json字段索引

MySQL并不支持直接为json数据类型创建索引,在MySQL8引入了间接创建的方式,可以间接指定json数据的成员或者元素作为创建索引的字段,而字段对应的数据类型我们需要手动指定。

从 MySQL 8.0.17 开始,InnoDB 支持创建多值索引,这是在存储值数组的 JSON 列上定义的二级索引,单个数据记录可以有多个索引记录。这样的索引使用关键部分定义,例如 CAST(data->’$.zipcode’ AS UNSIGNED ARRAY)。 MySQL 优化器自动使用多值索引来进行合适的查询,可以在 EXPLAIN 的输出中查看。

1.json字段的数据为json对象

添加索引

ALTER Table `table_name` ADD INDEX index_attrs_key(  
    (CAST( `business_attr` -> "$.attrKey"  as CHAR(32) ARRAY))
);

能够用到索引的查询方式

SELECT * FROM `table_name` WHERE JSON_OVERLAPS(`business_attr` -> "$.attrKey", CAST('"1000"' AS JSON ));

[p.s.]  如果是唯一匹配查询,可以使用MEMBER OF() 方法查询数组中是否存在某一值;

[p.s.]  mysql 8.024以上版本,可以使用JSON_CONTAINS() 查询数组中是否都包含某些值,交集(必须都包含)

2.json字段的数据为json数组

添加索引

ALTER Table `table_name` ADD INDEX index_attrs_arr_key(  
    (CAST( `business_attr` -> "$[*].attrArrKey" as CHAR(32) ARRAY))
);

能够用到索引的查询方式

SELECT * FROM `table_name` WHERE JSON_OVERLAPS(`business_attr` -> "$[*].attrArrKey", CAST('"1000"' AS JSON ));

mysql8.0 JSON文档

https://dev.mysql.com/doc/refman/8.0/en/json.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值