概述

我们都知道where条件如果在字段上带了函数就不会去走索引,不好优化,无意间了解到mysql一个新特性--虚拟列,专门处理这块问题的,下面一起来了解下吧~


Generated Column

在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默认的方式


语法

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


应用场景

假设有一个表,其中包含一个 date 类型的列 `SimpleDate` date

SimpleDate 是一个常用的查询字段,并需要对其执行日期函数,例如

SELECT ... WHERE dayofweek(SimpleDate) = 3 ...

此时的问题是 即使对 SimpleDate 建立索引,这个查询语句也无法使用,因为日期函数阻止了索引。

为了提高查询效率,通常要进行额外的操作,例如新建一个字段 SimpleDate_dayofweek,存放 dayofweek(SimpleDate) 的计算结果,然后对这列创建索引,SimpleDate_dayofweek 的值需要程序写入,例如使用触发器,在 SimpleDate 有变动时更新 这样查询就可以改为

3、构建姓名的虚拟列

alter table user add user_name varchar(20) generated always as (data->'$.name');

19个mysql性能优化要点解析(优化体系--详解MySQL)(1)

4、构建索引

alter table user add index idx_name(user_name);

19个mysql性能优化要点解析(优化体系--详解MySQL)(2)

5、测试是否用到索引

explain select * from user where user_name='"hwb"' \G;

19个mysql性能优化要点解析(优化体系--详解MySQL)(3)

可以看出用了索引了

6、插入新数据

此时的表的结构由于多出了user_name这一虚拟列,再插入别的数据要注意在表后指明插入列(不能给虚拟列插入数据)

insert into user(uid,data) values (NULL,'{"name":"test","address":"shantou"}');

19个mysql性能优化要点解析(优化体系--详解MySQL)(4)


做完发现这个实验好像不是那么好理解...应该对比一下加不加虚拟列有没走索引,可能会更容易让大家理解的...后面会分享更多devops和DBA方面的内容,感兴趣的朋友可以关注一下~

19个mysql性能优化要点解析(优化体系--详解MySQL)(5)

,