Mysql5.7学习之json类型(四)

背景

既然说到了json的虚拟列 那么必然会涉及到虚拟列的索引的创建

我们可以简单的比较一下和实体表的区别

首先我们使用 Mysql批量填充随机数据方法进行数据的填充

方案

创建表2 直接使用表1座create_table

create table user_2 as select  * from user;

这样的话我们看一下

user中的虚拟列变成了实际列

给user_2 建立特定的username索引

alter table user_2 add primary key(uid);
alter table user_2 add  index idx_name(virtual_name);

增加对应的索引

查看建表语句

mysql> show create table user_2\G
*************************** 1. row ***************************
       Table: user_2
Create Table: CREATE TABLE `user_2` (
  `uid` int(11) NOT NULL DEFAULT '0',
  `data` json DEFAULT NULL,
  `virtual_name` varchar(20) DEFAULT NULL,
  `address` varchar(50) DEFAULT NULL,
  `virtual_tel` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`uid`),
  KEY `idx_name` (`virtual_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
 
mysql> show create table user\G
*************************** 1. row ***************************
       Table: user
Create Table: CREATE TABLE `user` (
  `uid` int(11) NOT NULL AUTO_INCREMENT,
  `data` json DEFAULT NULL,
  `virtual_name` varchar(20) GENERATED ALWAYS AS (json_unquote(json_extract(`data`,'$.name'))) VIRTUAL,
  `address` varchar(50) DEFAULT NULL,
  `virtual_tel` varchar(20) GENERATED ALWAYS AS (json_unquote(json_extract(`data`,'$.tel'))) VIRTUAL,
  PRIMARY KEY (`uid`),
  KEY `idx_name_address` (`virtual_name`,`address`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1100009 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

测试

查看对应的sql语句

mysql> explain select * from user where virtual_name='徐二五'\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: user
   partitions: NULL
         type: ref
possible_keys: idx_name_address
          key: idx_name_address
      key_len: 63
          ref: const
         rows: 49
     filtered: 100.00
        Extra: NULL
1 row in set, 1 warning (0.04 sec)

而正常表的执行计划语句如下

mysql> explain select * from user_2 where virtual_name='徐二五'\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: user_2
   partitions: NULL
         type: ref
possible_keys: idx_name
          key: idx_name
      key_len: 63
          ref: const
         rows: 49
     filtered: 100.00
        Extra: NULL
1 row in set, 1 warning (0.00 sec)

两张表均可以用到对应的索引并且类型也完全一致

可以看到在单表数据过100w 其实json的性能也没有太多损失

mysql> select count(*)from user;
+----------+
| count(*) |
+----------+
|  1100007 |
+----------+
1 row in set (0.13 sec)

当然合适的索引至关重要!

猜你喜欢

转载自my.oschina.net/qixiaobo025/blog/1648099
今日推荐