解析OceanBase v4.2函数索引进行查询优化

一、如何通过函数索引来进行查询优化

函数索引是一种优化查询的技术,其主要作用在于提升包含函数调用的查询语句的执行速度。当查询语句中包含函数调用时,数据库系统需要逐行执行函数计算,这无疑会增加查询的复杂性,导致查询速度下降。然而,通过创建函数索引,我们可以在查询时直接定位到匹配的函数值,从而避免重复计算,提高查询的速度。下面,我们将通过一个具体示例来展示如何利用函数索引来优化查询性能。

假设有一张表t1,t1中有一个数据类型为date的列date_col:

create table t1(date_col date, sales_col int, name_col varchar(10));

如果需要获取3月份的数据,那么可以使用Month()函数来查询:

select * from t1 where month(date_col) = 3;

这种场景下,数据库需要为表中每行计算month(date_col),过滤掉不符合"month(date_col) = 3"的行。如果需要频繁使用月份信息来过滤数据,每次都需要重新计算month(date_col),就会造成大量开销。因此可以在date_col上建一个函数索引,将month(date_col)存储到了索引表中,来加速查询,创建函数索引的语句如下:

create index i1 on t1((month(date_col)));

建立索引后,查询时就可以直接使用该索引,避免了对每个行进行函数计算,提高了查询效率。

explain select * from t1 where month(date_col) = 3;
+-------------------------------------------------------------------------------------------------+
| Query Plan                                                                                      |
+-------------------------------------------------------------------------------------------------+
| ==================================================                                              |
| |ID|OPERATOR        |NAME  |EST.ROWS|EST.TIME(us)|                                              |
| --------------------------------------------------                                              |
| |0 |TABLE RANGE SCAN|t1(i1)|1       |7           |                                              |
| ==================================================                                              |
| Outputs & filters:                                                                              |
| -------------------------------------                                                           |
|   0 - output([t1.date_col], [t1.sales_col], [t1.name_col]), filter(nil), rowset=16              |
|       access([t1.__pk_increment], [t1.date_col], [t1.sales_col], [t1.name_col]), partitions(p0) |
|       is_index_back=true, is_global_index=false,                                                |
|       range_key([t1.SYS_NC19$], [t1.__pk_increment]), range(3,MIN ; 3,MAX),                     |
|       range_cond([t1.SYS_NC19$ = 3])                                                            |
+-------------------------------------------------------------------------------------------------+

二、OceanBase 4.2在MySQL模式下支持函数索引功能

OceanBase 4.1 以及之前的版本中,已在Oracle模式下支持了函数索引功能。OceanBase 4.2 在MySQL模式支持函数索引功能,兼容MySQL 8.0。

示例1:使用create index语句创建函数索引。

语法如下:

CREATE [UNIQUE | FULLTEXT | SPATIAL] INDEX index_nameON tbl_name (expr,...)[index_option] ...key_part: (expr) [ASC | DESC]

expr是一个合法的函数索引表达式,且允许是布尔表达式,例如"c1=c1"。与MySQL不同的是,OceanBase禁止在函数索引的定义中引用生成列。

例如以下语句在t1_func表上创建了一个索引定义是c1+c2 < 1的函数索引i1。

create table t1_func(c1 int, c2 int);
create index i1 on t1_func ((c1+c2 < 1));

示例2:使用alter table语句创建函数索引。

语法如下:

ALTER TABLE tbl_name[alter_option [, alter_option] ...][partition_options]alter_option: {table_options| ADD {INDEX | KEY} [index_name][index_type] (key_part,...) [index_option] ...| ADD SPATIAL [INDEX | KEY] [index_name](key_part,...) [index_option] ...| ...key_part: (expr) [ASC | DESC]

例如以下语句在t1_func上添加了3个函数索引,其中一个名字是i2,另外两个由系统自动生成的名称,格式为‘functional_index’前缀加编号。

alter table t1_func add index ((concat(c1,'a')));
alter table t1_func add index ((c1+1));
alter table t1_func add index i2 ((concat(c1,'a')));

示例3:使用create table语句在建表时创建函数索引。

语法如下:

CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name(create_definition,...)[table_options][partition_options]create_definition: {col_name column_definition| {INDEX | KEY} [index_name] [index_type] (key_part,...)[index_option] ...| SPATIAL [INDEX | KEY] [index_name] (key_part,...)[index_option] ...| [CONSTRAINT [symbol]] UNIQUE [INDEX | KEY][index_name] [index_type] (key_part,...)[index_option] ......
}key_part: (expr) [ASC | DESC]

例如以下语句在创建表t2_func时,创建了一个函数索引i1。

create table t2_func (c1 int, c2 int, index i1 ((c1+1)), unique key ((c1+c2)));

可以使用show create table语句查看创建的函数索引:

show create table t1_func;
+---------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table   | Create Table                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
+---------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t1_func | CREATE TABLE `t1_func` (`c1` int(11) DEFAULT NULL,`c2` int(11) DEFAULT NULL,KEY `i1` (((`c1` + `c2`) < 1)) BLOCK_SIZE 16384 LOCAL,KEY `functional_index` (concat(`c1`,'a')) BLOCK_SIZE 16384 LOCAL,KEY `functional_index_2` ((`c1` + 1)) BLOCK_SIZE 16384 LOCAL,KEY `i2` (concat(`c1`,'a')) BLOCK_SIZE 16384 LOCAL
) DEFAULT CHARSET = utf8mb4 ROW_FORMAT = DYNAMIC COMPRESSION = 'lz4_1.0' REPLICA_NUM = 1 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 0 |
+---------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+show create table t2_func;
+---------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table   | Create Table                                                                                                                                                                                                                                                                                                                                                                       |
+---------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t2_func | CREATE TABLE `t2_func` (`c1` int(11) DEFAULT NULL,`c2` int(11) DEFAULT NULL,UNIQUE KEY `functional_index` ((`c1` + `c2`)) BLOCK_SIZE 16384 LOCAL,KEY `i1` ((`c1` + 1)) BLOCK_SIZE 16384 LOCAL
) DEFAULT CHARSET = utf8mb4 ROW_FORMAT = DYNAMIC COMPRESSION = 'lz4_1.0' REPLICA_NUM = 1 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 0 |
+---------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

也可以使用show index命令来查看已创建的函数索引,例如:

show index from t1_func;
+---------+------------+--------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+-----------+---------------+---------+---------------------+
| Table   | Non_unique | Key_name           | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment   | Index_comment | Visible | Expression          |
+---------+------------+--------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+-----------+---------------+---------+---------------------+
| t1_func |          1 | i1                 |            1 | SYS_NC18$   | A         |        NULL | NULL     | NULL   | YES  | BTREE      | available |               | YES     | ((`c1` + `c2`) < 1) |
| t1_func |          1 | functional_index   |            1 | SYS_NC19$   | A         |        NULL | NULL     | NULL   | YES  | BTREE      | available |               | YES     | concat(`c1`,'a')    |
| t1_func |          1 | functional_index_2 |            1 | SYS_NC20$   | A         |        NULL | NULL     | NULL   | YES  | BTREE      | available |               | YES     | (`c1` + 1)          |
| t1_func |          1 | i2                 |            1 | SYS_NC19$   | A         |        NULL | NULL     | NULL   | YES  | BTREE      | available |               | YES     | concat(`c1`,'a')    |
+---------+------------+--------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+-----------+---------------+---------+---------------------+show index from t2_func;
+---------+------------+------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+-----------+---------------+---------+---------------+
| Table   | Non_unique | Key_name         | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment   | Index_comment | Visible | Expression    |
+---------+------------+------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+-----------+---------------+---------+---------------+
| t2_func |          1 | i1               |            1 | SYS_NC18$   | A         |        NULL | NULL     | NULL   | YES  | BTREE      | available |               | YES     | (`c1` + 1)    |
| t2_func |          0 | functional_index |            1 | SYS_NC19$   | A         |        NULL | NULL     | NULL   | YES  | BTREE      | available |               | YES     | (`c1` + `c2`) |
+---------+------------+------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+-----------+---------------+---------+---------------+

三、OceanBase 4.2禁止非确定性函数用于函数索引

OceanBase 4.2版本禁止了一些非确定性的系统函数被用于创建函数索引和生成列,以提升稳定性。这些系统函数的结果会随着系统或用户环境的变化而变化的函数,例如:

select current_time();
+----------------+
| current_time() |
+----------------+
| 20:44:22       |
+----------------+select current_time();
+----------------+
| current_time() |
+----------------+
| 20:44:24       |
+----------------+

MySQL模式

以下函数被禁止用于生成列和函数索引:

aes_decryptfrom_unixtimestatement_digest
aes_encrypthost_ipsys_privilege_check
benchmarkicu_versionsysdate
connection_idis_serving_tenanttime_to_usec
current_datelast_excution_idunix_timestamp
current_timelast_insert_idusec_to_time
current_timestamplnnvluser
current_userlocaltimestamputc_date
current_user_privmysql_portutc_time
databasename_constutc_timestamp
des_decryptob_versionuuid
des_encryptranduuid_short
des_hex_strrandom_bytesvalidate_password_strength
dumprow_countversion
encryptrpc_portweight_string
found_rowssleep

一些时间相关的系统函数禁止在参数为TIME类型时用于函数索引,例如:

create table time_func(c1 time, c2 date);
create index i1 on time_func((date(c1)));
ERROR 3758 (HY000): Expression of functional index contains a disallowed function.

涉及以下函数:

adddatedayofyeartimestampdiff
datelast_dayto_days
date_submonthweek
datediffmonthnameweekday
dayquarterweekofyear
daynametimestampyear
dayofmonthtimestamp_nvlyearweek
dayofweektimestampadd

此外,cast函数将time类型的参数转换成非time的其他时间类型,或者将timestamp类型的参数转换为非timestamp的其他数据类型时,也被禁止用于生成列和函数索引,例如:

create index i1 on time_func((cast(c1 as DATE)));
ERROR 3758 (HY000): Expression of functional index contains a disallowed function.

Oracle模式

与之前的版本相比,4.2版本在Oracle模式下新增禁止了以下函数用于生成列和函数索引:

dumpob_versionrpc_port
host_ipregexp_countscn_to_timestamp
is_serving_tenantregexp_instrtimestamp_to_scn
last_trace_idregexp_substr

以下系统函数在参数是字符串类型时禁止用于函数索引:

add_monthsnext_day
last_daytimestamp_nvl
months_between

例如:

create table t1(c1 date, c2 varchar(40), c3 timestamp);
create index i1 on t1(ADD_MONTHS(c2, 1));
ORA-01743: only pure functions can be indexed

此外,cast函数在将字符串转为时间类型、将时间类型转为字符串、将不带timezone信息的时间类型转为带timezone信息的时间类型的情况下禁止用于函数索引,例如:

create table t2(c1 varchar(20), c2 date, c3 TIMESTAMP WITH TIME ZONE, c4 number);
create index i1 on t2(cast(c1 as DATE));
ORA-01743: only pure functions can be indexedcreate index i1 on t2(cast(c2 as TIMESTAMP WITH TIME ZONE));
ORA-01743: only pure functions can be indexedcreate index i1 on t2(cast(c3 as VARCHAR(10)));
ORA-01743: only pure functions can be indexed

四、总结

Oceanbase 4.2版本支持了在MySQL模式下创建和使用函数索引,并且禁止了部分非确定性函数用于创建函数索引和生成列以提升稳定性。但是其中部分函数在MySQL和Oracle中是允许用于函数索引的,例如:

(Mysql 8.0.31)
mysql> create table time_func(c1 timestamp, c2 date);
Query OK, 0 rows affected (0.04 sec)mysql> create index i1 on time_func((date(c1)));
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

Oceanbase后续版本将会放开对这些函数的限制,进一步提升兼容性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/534.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C语言】多字节字符、宽字符(涉及字符集和编码)

字符集、编码&#xff1a; 字符集&#xff1a;一个系统支持的所有抽象字符的集合。字符是各种文字和符号的总称&#xff0c;包括各国家文字、标点符号、图形符号、数字等。例如&#xff1a;ASCII、Unicode、GB2312、GBK、GB18030、BIG5(繁体中文) ... 编码方式&#xff1a;符号…

【Flutter】自动生成图片资源索引插件一:FlutterAssetRefGenerator

介绍 FlutterAssetRefGenerator 插件&#xff1a;windows上 点击生成图片索引按钮后&#xff0c;pubspec.yaml 会出现中文乱码&#xff0c;需要手动改乱码&#xff1b;mac上没问题。 优点&#xff1a;点击图标自动生成。 目录 介绍一、安装二、使用 一、安装 安装FlutterAsset…

移动端不居中问题/安卓和ios下line-height上下居中 css兼容问题

移动端开发过程&#xff0c;经常会写带0.5px边框角标类的样式&#xff0c;直接使用border设置0.5px边框&#xff0c;ios有些机型会出现显示不完整的情况。所以改用伪元素方法实现边框。代码如下&#xff1a; .comment-entry::after{content: ;position: absolute;left: 0;top: …

快速IO的方式|Java快读模板

处理IO的方式&#xff1a; 处理输入和输出的方式&#xff1a; C&#xff1a;cin / cout Java&#xff1a;Scanner / System.out 但是这两种有超时的风险 那么C处理方式&#xff1a;直接改为scanf / printf &#xff0c;也就是C语言中的读写方式 Java处理方式&#xff1a;准备一…

Python 中 + 和 += 赋值操作的性能比较

1. 问题背景 在 Python 中&#xff0c;我们可以通过 和 … 完成累加操作&#xff0c;在实际开发过程中我们一般会优先选择 &#xff0c;然而最近在对比 和 … 的性能时出现了 反而更慢的现象。因此&#xff0c;我们决定对此问题进行深入探讨。 2. 解决方案 为了准确地…

C语言---贪吃蛇(一)---准备工作

文章目录 前言1.Win32 API介绍1.1.Win32 API1.2. 控制台程序1.3.控制台屏幕上的坐标[COORD](https://learn.microsoft.com/zh-cn/windows/console/coord-str)1.4.[GetStdHandle](https://learn.microsoft.com/zh-cn/windows/console/getstdhandle)1.5.[GetConsoleCursorInfo](h…

视频太大怎么压缩变小?8种方法随时压缩视频大小

视频太大怎么压缩变小&#xff1f;视频压缩方式分为两种&#xff0c;有损压缩和无损压缩&#xff0c;什么是有损什么是无损压缩&#xff0c;什么时候视频用无损压缩更好&#xff1f;什么时候用有损压缩更好&#xff1f;如何调整视频参数实现基本无损压缩&#xff1f; 今天就借助…

九章云极DataCanvas AIDC OS智算操作系统正式发布,开启AI智算新纪元

4月18日&#xff0c;2024九章云极DataCanvas智算操作系统新品发布会于北京隆重召开&#xff0c;全新产品DATACANVAS AIDC OS智算操作系统&#xff08;以下简称AIDC OS&#xff09;正式官宣。AIDC OS以卓越的AI技术实力和AI基础软件为根基&#xff0c;以重新定义和突破传统为创新…

我独自升级崛起在哪里下载 我独自升级崛起一键下载方法极速体验

我独自升级崛起在哪里下载 我独自升级崛起一键下载方法极速体验 最近在游戏圈内爆火的一款游戏《我独自升级&#xff1a;崛起》是一款由韩国漫画改编而成的热门多人网络在线联机游戏&#xff0c;这款游戏是一款的角色扮演游戏&#xff0c;游戏有着引人入胜的剧情模式。玩家们…

Docker 入门指南:快速上手 Docker

Docker 是一种开源的容器化平台&#xff0c;它可以帮助开发者轻松地打包、发布和运行应用程序。本指南将介绍 Docker 的基本概念和常用操作&#xff0c;帮助你快速入门 Docker 技术。 1. 安装 Docker 首先&#xff0c;你需要在你的操作系统上安装 Docker。Docker 支持多种操作…

m4a转wav怎么转?3个简单的转换方法~

随着音频的迅猛发展&#xff0c;不同的音频文件格式应运而生&#xff0c;其中M4A和WAV都备受欢迎。M4A格式的兴起始于对音质和压缩效率的双重追求&#xff0c;而WAV则因其高保真特性而成为专业录音室的首选。 M4A格式的由来 M4A格式最初是由苹果公司引入的&#xff0c;旨在提供…

ZCC5080E USB 5V 输入 1A 双节锂电池充电管理 IC替代CS5080E

概要&#xff1a; ZCC5080E 是一款 5V USB 适配器输入&#xff0c;高精度双节锂离子电池充电管理芯片。具有0V充电功能&#xff0c;涓流充电、恒流充电、恒压充电和自动截止、自动再充等一套完整充电循环的充电管理芯片。芯片内部特设 9V 抗浪涌&#xff0c;芯片应用更安全可…

6、JVM-JVM调优工具与实战

前置启动程序 事先启动一个web应用程序&#xff0c;用jps查看其进程id&#xff0c;接着用各种jdk自带命令优化应用 Jmap 此命令可以用来查看内存信息&#xff0c;实例个数以及占用内存大小 jmap -histo 14660 #查看历史生成的实例 jmap -histo:live 14660 #查看当前存活的实…

探索人工智能绘图的奇妙世界

探索人工智能绘图的奇妙世界 人工智能绘图的基本原理机器之美&#xff1a;AI绘图作品AI绘图对艺术创作的影响未来展望与挑战图书推荐&#x1f449;AI绘画教程&#xff1a;Midjourney使用方法与技巧从入门到精通内容简介获取方式&#x1f449;搜索之道&#xff1a;信息素养与终身…

CSS 实现视差滚动效果

一、是什么 视差滚动&#xff08;Parallax Scrolling&#xff09;是指多层背景以不同的速度移动&#xff0c;形成立体的运动效果&#xff0c;带来非常出色的视觉体验 我们可以把网页解刨成&#xff1a;背景层、内容层、悬浮层 当滚动鼠标滑轮的时候&#xff0c;各个图层以不…

启明云端ESP32-S3+车载桥接器案例,能实现对车载产品集控

最近房车旅行很盛行&#xff0c;谁不想五一自驾游开车去外面玩&#xff1f;为了能提升用户体验&#xff0c;车企房车智能化升级越来越普遍&#xff0c;接下来小启给大家讲一个案例&#xff0c;启明云端ESP32-S3车载桥接器&#xff0c;感兴趣的可以看看。 一、ESP32-S3车载桥接器…

分享4款免费ai绘画工具!

随着人工智能技术的飞速发展&#xff0c;AI绘画工具已经逐渐走入了我们的日常生活。这些工具不仅能够简化绘画过程&#xff0c;更能让普通人体验到艺术创作的乐趣。今天&#xff0c;我们就来盘点一下那些值得一试的免费AI绘画工具&#xff0c;看看它们如何让我们的创作欲望得到…

说真的,项目经理不太需要PMP

事实上&#xff0c;很多成功的项目经理并没有PMP证书&#xff0c;但他们凭借丰富的项目经验和对项目管理的深入理解&#xff0c;成功完成了许多复杂的项目。 PMP是一个全球公认的项目管理专业认证&#xff0c;它代表了项目经理在项目管理理论和方法上的专业知识和技能。所以会…

如何在 Linux 和 Mac 终端命令中添加别名

在本文中&#xff0c;我们将探讨一种简单的技巧&#xff0c;可以节省您在终端中输入重复命令的时间。 作为开发者&#xff0c;我们花费大量时间在终端上执行命令。无论是浏览目录、运行脚本、更改 Node.js 版本还是版本控制命令&#xff0c;手动输入每个命令都是一项耗时的任务…

有效的括号 + 点击消除 || 匹配问题

目录 点击消除&#xff1a; 有效的括号&#xff1a; 点击消除&#xff1a; 点击消除_牛客题霸_牛客网 (nowcoder.com)https://www.nowcoder.com/practice/8d3643ec29654cf8908b5cf3a0479fd5?tpId308&tqId40462&ru/exam/oj 如题目所述&#xff0c; 示例1&#xf…