MYSQL 8 的功能是的挖掘一下,PS ,SYS 系列年后会持续更新,本期的说说 MYSQL 8 的 functional Indexes,对于这个功能本身DBA 应该不陌生,但对于MYSQL 的DBA 本身来说,这个就陌生了,尤其是还在 5.X 上打转的 MYSQL DBA。
举例:下面的操作中的对于一个特定的查询看看是否陌生
1 表t_user 是我们此次的测试表
2 这里的查询语句是
select select avg(age) from t_user where month(create_time) = 10;
想想这样的查询语句开发都会写出来,逻辑是统计10月份来的员工的平均年龄。如果是MYSQL 的开发或DBA 可能会建议写成这样
select select avg(age) from t_user where create_time between "2021-10-01" and "2021-10-31";
通过时间的维度来进行计算,并且通过create_time 索引来加速查询的速度,但这样的处理的建议,实际上并不是一个好的方法原因
1 增加了开发撰写语句的负担,提高实现逻辑的复杂性。
2 日期的范围很难把握,时间短可以,但如果时间长,则计算的速度可能也不会有较大的提升。
所以如果有能支持,这样写法的索引,函数索引,那么解决问题的方法就简单了
select select avg(age) from t_user where month(create_time) = 10;
这就是MYSQL 8.013 后支持的函数索引,让以上的语法也能支持索引的功能。
我们就先建立一个相关的索引,但情况并为改变,还是无法走索引
alter table t_user add index ((MONTH(create_time)));
explain select avg(age) from t_user where month(create_time) = 12;
上面的这个例子可能比较简单,实际上函数索引本身可以很复杂,如
两个字段的和来建立索引, 并且在计算中对函数索引中计算后的值,进行排序。
函数索引本身也是有一些限制的,在MYSQL 中
1 不能建立两个毫无关系的字段的或以上的索引如 index ((col1),(col2))
2 主键不能建立函数索引
3 外键不能建立函数索引
4 全文索引以及spaital 索引不能建立索引
5 函数索引不能成为部分索引的一部分
并且通过MYSQL 5.7 支持虚拟列的方式将函数索引联合使用,直接在MYSQL 得表中产生一个虚拟的列作为函数索引的目的地。
alter table t_user add column create_month tinyint generated always as (MONTH(create_time)) VIRTUAL;
直接在查询中使用这个虚拟的列。
MYSQL 8 从这几年在开发中的功能提升并未停止,而大部分企业还留在MYSQL 5.7 并为发现MYSQL 8 的开发中的新的功能以及MYSQL 8 功能更新下宣传不够,才是目前 MYSQL 数据库需要解决的问题,让更多的企业升级到MYSQL 8 并使用更新的高可用方式,才是MYSQL 后续发展的可持续的道路。
参考官方文档地址
https://dev.mysql.com/doc/refman/8.0/en/create-index.html#create-index-functional-key-parts