首页 > 数据库 >MySQL8.0 新特性函数索引

MySQL8.0 新特性函数索引

时间:2024-07-13 09:30:39浏览次数:9  
标签:function 函数 create 索引 MySQL8.0 time NULL 07

MySQL 8.0 中的函数索引(Function-Based Index)是一种高级索引特性,它允许数据库管理员或开发者对表中的列执行表达式计算后的结果进行索引,而不是直接对列值或列的前缀值进行索引。这种索引技术可以显著提高查询性能,特别是在需要对列值进行复杂计算或转换的查询场景中。

MySQL8.0.13引入函数索引(Oracle,postgresql都有该项功能)。

一、函数索引的定义与作用

函数索引是对表中的列执行表达式计算后的结构进行索引,而不是对列或列前缀值。它允许对未直接存储在表中的数据进行索引,为应用程序提供了极大的便利和性能提升。例如,你可能需要经常查询某个日期字段的年份部分,通过函数索引,你可以直接对年份部分进行索引,而无需在每次查询时都执行日期转换操作。

二、函数索引的创建

在MySQL 8.0中,创建函数索引的语法与普通索引类似,但需要注意以下几点:

  • 索引表达式:函数索引对应的表达式需要用括号()括起来。
  • 表达式复杂性:索引表达式可以包括函数、算术运算、比较操作等,但应尽可能保持简单,以避免索引维护的开销过大。
  • 索引类型:函数索引可以是普通索引、唯一索引等,具体取决于你的需求。

1、创建测试表及数据

create table t_function(id int primary key auto_increment,name  varchar(100),create_time datetime);
insert into t_function(name,creatE_time) values('function-index','2024-07-01 12:00:00');
insert into t_function(name,creatE_time) values('mysql5.7.28-version','2024-07-01 15:00:00');
insert into t_function(name,creatE_time) values('version-mysql8.0.28','2024-07-01 21:30:00');
insert into t_function(name,creatE_time) values('create-index-indexname','2024-07-02 01:30:00');
insert into t_function(name,creatE_time) values('on-tablename-column','2024-07-02 03:30:00');
insert into t_function(name,creatE_time) values('column-function','2024-07-02 07:32:00');
insert into t_function(name,creatE_time) values('index-indexname-column','2024-07-02 10:32:00');
insert into t_function(name,creatE_time) values('alter-table-tablename','2024-07-02 15:32:00');
insert into t_function(name,creatE_time) values('add-index-indexname','2024-07-02 20:32:00');
insert into t_function(name,creatE_time) values('use-superdb','2024-07-03 02:56:00');
insert into t_function(name,creatE_time) values('show-tables','2024-07-03 08:41:00');
insert into t_function(name,creatE_time) values('show-index-from-t_function','2024-07-03 16:20:00');
commit;

2、创建函数索引

在将上述的表及数据在MySQL8.0的实例上创建,然后创建create_time的函数索引,SQL如下

(root@localhost)[superdb]> alter table t_function add key idx_t_function_create_time(create_time);
Query OK, 0 rows affected (0.23 sec)
Records: 0  Duplicates: 0  Warnings: 0

(root@localhost)[superdb]> alter table t_function add key idx_t_function_create_time_2 ((date(create_time)));
Query OK, 0 rows affected (0.08 sec)
Records: 0  Duplicates: 0  Warnings: 0

3、按时间查询

(root@localhost)[superdb]> select * from t_function where date(create_time)='2024-07-01';
+----+---------------------+---------------------+
| id | name                | create_time         |
+----+---------------------+---------------------+
|  1 | function-index      | 2024-07-01 12:00:00 |
|  2 | mysql5.7.28-version | 2024-07-01 15:00:00 |
|  3 | version-mysql8.0.28 | 2024-07-01 21:30:00 |
+----+---------------------+---------------------+
3 rows in set (0.02 sec)

(root@localhost)[superdb]> explain select * from t_function where date(create_time)='2024-07-01';
+----+-------------+------------+------------+------+------------------------------+------------------------------+---------+-------+------+----------+-------+
| id | select_type | table      | partitions | type | possible_keys                | key                          | key_len | ref   | rows | filtered | Extra |
+----+-------------+------------+------------+------+------------------------------+------------------------------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | t_function | NULL       | ref  | idx_t_function_create_time_2 | idx_t_function_create_time_2 | 4       | const |    3 |   100.00 | NULL  |
+----+-------------+------------+------------+------+------------------------------+------------------------------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.02 sec)

(root@localhost)[superdb]> explain select * from t_function where create_time>='2024-07-01' and create_time<date_add('2024-07-01',interval '1' day);
+----+-------------+------------+------------+-------+----------------------------+----------------------------+---------+------+------+----------+-----------------------+
| id | select_type | table      | partitions | type  | possible_keys              | key                        | key_len | ref  | rows | filtered | Extra                 |
+----+-------------+------------+------------+-------+----------------------------+----------------------------+---------+------+------+----------+-----------------------+
|  1 | SIMPLE      | t_function | NULL       | range | idx_t_function_create_time | idx_t_function_create_time | 6       | NULL |    3 |   100.00 | Using index condition |
+----+-------------+------------+------------+-------+----------------------------+----------------------------+---------+------+------+----------+-----------------------+
1 row in set, 1 warning (0.01 sec)

4、查看表t_function 索引

show columns and show index statements now support an optional EXTENDED keyword that causs statement output to include information about hidden columns and indexes that MySQL uses internally and are not accessible by users.

(root@localhost)[superdb]> show index from t_function;
+------------+------------+------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+-----------------------------+
| Table      | Non_unique | Key_name                     | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression                  |
+------------+------------+------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+-----------------------------+
| t_function |          0 | PRIMARY                      |            1 | id          | A         |          12 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL                        |
| t_function |          1 | idx_t_function_create_time   |            1 | create_time | A         |          12 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL                        |
| t_function |          1 | idx_t_function_create_time_2 |            1 | NULL        | A         |           3 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | cast(`create_time` as date) |
+------------+------------+------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+-----------------------------+
3 rows in set (0.01 sec)

(root@localhost)[superdb]> show extended index from t_function;
+------------+------------+------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+-----------------------------+
| Table      | Non_unique | Key_name                     | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression                  |
+------------+------------+------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+-----------------------------+
| t_function |          0 | PRIMARY                      |            1 | id          | A         |          12 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL                        |
| t_function |          0 | PRIMARY                      |            2 | DB_TRX_ID   | A         |        NULL |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL                        |
| t_function |          0 | PRIMARY                      |            3 | DB_ROLL_PTR | A         |        NULL |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL                        |
| t_function |          0 | PRIMARY                      |            4 | name        | A         |        NULL |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL                        |
| t_function |          0 | PRIMARY                      |            5 | create_time | A         |        NULL |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL                        |
| t_function |          1 | idx_t_function_create_time   |            1 | create_time | A         |          12 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL                        |
| t_function |          1 | idx_t_function_create_time   |            2 | id          | A         |        NULL |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL                        |
| t_function |          1 | idx_t_function_create_time_2 |            1 | NULL        | A         |           3 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | cast(`create_time` as date) |
| t_function |          1 | idx_t_function_create_time_2 |            2 | id          | A         |        NULL |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL                        |
+------------+------------+------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+-----------------------------+
9 rows in set (0.00 sec)

可见,在MySQL8.0 创建对应的函数索引后,不改变SQL写法的前提下,查询的列上进行对应的函数计算后也可以走索引

5、MySQL5.7.X版本

因MySQL5.7不支持函数索引,所以需要修改SQL写法来实现走索引(或者使用虚拟列的方式)

  • 创建表及插入数据同第1
  • 在create_time字段上创建索引
  • 查询创建时间是2024-07-01那天的所有记录
mysql> select * from t_function where date(create_time)='2024-07-01';
+----+---------------------+---------------------+
| id | name                | create_time         |
+----+---------------------+---------------------+
|  1 | function-index      | 2024-07-01 12:00:00 |
|  2 | mysql5.7.28-version | 2024-07-01 15:00:00 |
|  3 | version-mysql8.0.28 | 2024-07-01 21:30:00 |
+----+---------------------+---------------------+
3 rows in set (0.00 sec)

mysql> explain select * from t_function where date(create_time)='2024-07-01';
+----+-------------+------------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table      | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+------------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | t_function | NULL       | ALL  | NULL          | NULL | NULL    | NULL |   12 |   100.00 | Using where |
+----+-------------+------------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.05 sec)
-- 执行计划中可以看出是进行了全表扫描

修改SQL写法来实现走索引(或者使用虚拟列的方式)

mysql> select * from t_function where create_time>='2024-07-01' and create_time<date_add('2024-07-01',interval '1' day);
+----+---------------------+---------------------+
| id | name                | create_time         |
+----+---------------------+---------------------+
|  1 | function-index      | 2022-04-01 12:00:00 |
|  2 | mysql5.7.28-version | 2022-04-01 15:00:00 |
|  3 | version-mysql8.0.28 | 2022-04-01 21:30:00 |
+----+---------------------+---------------------+
3 rows in set (0.00 sec)
-- 等价修改SQL写法来第一种实现走索引
mysql> select * from t_function where create_time between '2024-07-01' and date_add('2022-07-01',interval '1' day);
+----+---------------------+---------------------+
| id | name                | create_time         |
+----+---------------------+---------------------+
|  1 | function-index      | 2024-07-01 12:00:00 |
|  2 | mysql5.7.28-version | 2024-07-01 15:00:00 |
|  3 | version-mysql8.0.28 | 2024-07-01 21:30:00 |
+----+---------------------+---------------------+
3 rows in set (0.05 sec)
-- 等价修改SQL写法第二种来实现走索引
mysql> select * from t_function where create_time>='2024-07-01' and create_time<date_add('2022-04-01',interval '1' day);
+----+---------------------+---------------------+
| id | name                | create_time         |
+----+---------------------+---------------------+
|  1 | function-index      | 2024-07-01 12:00:00 |
|  2 | mysql5.7.28-version | 2024-07-01 15:00:00 |
|  3 | version-mysql8.0.28 | 2024-07-01 21:30:00 |
+----+---------------------+---------------------+
3 rows in set (0.05 sec)
-- 查看执行计划
mysql> explain select * from t_function where create_time>='2024-07-01' and create_time<date_add('2022-04-01',interval '1' day);
+----+-------------+------------+------------+-------+----------------------------+----------------------------+---------+------+------+----------+-----------------------+
| id | select_type | table      | partitions | type  | possible_keys              | key                        | key_len | ref  | rows | filtered | Extra                 |
+----+-------------+------------+------------+-------+----------------------------+----------------------------+---------+------+------+----------+-----------------------+
|  1 | SIMPLE      | t_function | NULL       | range | idx_t_function_create_time | idx_t_function_create_time | 6       | NULL |    3 |   100.00 | Using index condition |
+----+-------------+------------+------------+-------+----------------------------+----------------------------+---------+------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)

三、函数索引的使用场景

函数索引特别适用于以下场景:

  • 日期和时间的计算:如查询特定年份、月份或日期的记录。
  • 字符串处理:如查询字符串的某个子串或进行大小写不敏感的匹配。
  • 数值计算:如查询某个数值范围经过计算后落在特定区间的记录。

四、注意事项

  • 索引维护:函数索引的维护成本可能比普通索引更高,因为每次插入、更新或删除记录时,都需要重新计算索引表达式。
  • 索引选择性:函数索引的选择性(即索引列中不同值的比例)对于查询性能至关重要。选择性较低的索引可能无法提供显著的性能提升。
  • 兼容性:不是所有的MySQL存储引擎都支持函数索引。例如,InnoDB存储引擎支持函数索引,但MyISAM则不支持。

五、总结

MySQL 8.0 的函数索引为数据库管理员和开发者提供了更灵活的索引选择,可以显著提高查询性能。然而,在使用函数索引时,需要仔细考虑索引的维护成本、选择性和兼容性等因素。通过合理使用函数索引,可以优化数据库查询性能,提升应用程序的整体性能。

标签:function,函数,create,索引,MySQL8.0,time,NULL,07
From: https://blog.csdn.net/zxrhhm/article/details/140377658

相关文章

  • 类的继承 虚函数 纯虚函数
    定义:classTIme:publicEnt//EntTime是Ent的子集继承Ent类的公开变量//Time可共享Ent,Ent不能共享Time类虚函数:功能:允许在子类中重写方法也就是本例子中的Time类中,在Ent类中重写virtual让它做其他事情例如:classEnt{public: virtualstd::s......
  • 【C语言】字符串与相关操作函数
    字符串思路分析在注释文章目录字符串一、字符串的定义1.使用sizeof()计算他们的长度二、sizeof和strlen的区别1.sizeof操作符2.strlen函数三、动态开辟字符串1.malloc函数2.realloc函数3.free函数4.memset函数四、几种字符串常用的API1.strncpy函数2.asse......
  • SQL优化-索引
    什么是索引?索引(index)是帮助MySQL高效获取数据的数据结构(有序)。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引。索引的特点:索引结......
  • 实验9 存储过程与函数的创建管理实验
    一、实验目的:理解存储过程和函数的概念。掌握创建存储过程和函数的方法。掌握执行存储过程和函数的方法。掌握游标的定义、使用方法。二、实验内容1.某超市的食品管理的数据库的Food表,Food表的定义如表所示,Food表的定义各列有如下数据:‘QQ饼干’,‘QQ饼干厂’,2.5,‘2......
  • c语言的简易教法—— 函数递归
    文章目录一、什么是递归?1.1递归的思想1.2递归的限制条件二、递归案例2.1案例1:求n的阶层2.1.1分析2.1.2递归函数(Fact)的代码实现2.1.3测试:main函数实现2.1.4运行结果和画图推演2.1.5扩展:迭代方法求解n的阶乘2.2案例2:顺序打印⼀个整数的每⼀位2.2.1分析2.2.2打印数(p......
  • 如何在函数中使用return返回axios的请求结果
    使用场景:在添加学生上课记录的时候,需要先获取学生的剩余课时,需要通过接口获取。所以需要封装一个方法,能够通过接口获取学生的课时数量。解决方案:通过异步解决封装方法的代码如下:constgetStudentCourseCount=async()=>{letnum=0awaitaxios({method:......
  • 10个Python函数参数进阶用法及代码优化
    目录1.默认参数值:让函数更加灵活2.关键字参数:清晰的调用方式3.*args:拥抱不确定数量的位置参数4.**kwargs:处理不确定数量的关键字参数5.参数解包:简化多参数的传递6.命名关键字参数:限制关键字参数7.局部变量与全局变量:理解作用域8.高级:装饰器(@decorator)9.Lambd......
  • python每日学习4:函数的定义和各类参数定义与用法
    目录目录一、函数的定义二、参数的定义和用法1、必选参数2、默认参数3、可变参数4、关键字参数5、命名关键字参数三、参数在实际操作中的要求一、函数的定义1、函数代码块以def关键词开头,后接函数名称和圆括号()2、在圆括号内定义传入参数3、函数的第一行语句可以......
  • 我的MYSQL学习心得, 自定义存储过程和函数
    转载:https://www.cnblogs.com/lyhabc/p/3793524.html我的MYSQL学习心得(一)简单语法我的MYSQL学习心得(二)数据类型宽度我的MYSQL学习心得(三)查看字段长度我的MYSQL学习心得(四)数据类型我的MYSQL学习心得(五)运算符我的MYSQL学习心得(六)函数我的MYSQL学习心得(七)查询我的MYSQ......
  • 动态添加HTML时onclick函数参数传递
    onclick函数动态传参1.参数为数值类型时:var tmp=123;var strHTML="<divonclick=func(" +tmp+")>点击弹出数据及其类型</div>";info.append(strHTML); function func(tmp){    alert(typeof tmp+"" +tmp);}string12......