KingbaseES 与Oracle 函数稳定性对于性能影响差异比较
一、函数的属性
KingbaseES 函数在定义时有三种稳定性级别:volatile、stable 和 immutable。默认情况下,创建函数的稳定性为volatile。以下是这三种函数的区别:
- Volatile 函数可以做任何事情,包括修改数据库。在调用中,输入同样的参数可能会返回不同的结果,比如:currtid 。在一个Query中,对于每一行都会重新计算该函数。
- Stable 函数不能修改数据库,单个Query中所有行给定同样的参数确保返回相同的结果。这种稳定级别允许优化器将多次函数调用转换为一次。在索引扫描的条件中使用这种函数是可行的,因为索引扫描只计算一次比较值(comparison value),而不是每行都计算一次。
- Immutable 函数不能修改数据库,在任何情况下,只要输入参数相同,返回结果就相同。这种级别的函数,优化器可以提前进行计算,在查询过程中作为常量参数。比如:SELECT...WHERE x=2+2 可以简化为SELECT...WHERE x=4。
- Deterministic 这是KingbaseES 为了与oracle 兼容而增加的一个属性,等价于 immutable 。
稳定性级别使得优化器可以判断不同函数的行为。为了得到最佳的优化结果,在创建函数时我们应该指定严格的稳定性级别。
二、不同属性对于性能的影响
以下举例说明函数的属性影响相同参数情况多次执行的效率。
1、构建函数和数据
create table test(id integer); 并插入100条完全相同的数据。
create or replace function test_volatile(id integer)
returns bigint
volatile
language sql
as
$$ select count(*) from t1 $$ ;
/ create or replace function test_stable(id integer)
returns bigint
stable
language sql
as
$$ select count(*) from t1 $$ ;
/ create or replace function test_immutable(id integer)
returns bigint
immutable
language sql
as
$$ select count(*) from t1 $$ ;
/
2、以列为参数调用函数
可以看到三个函数调用时间基本没有差别,因为,传入的参数是id 变量值(虽然实际值是相同的)。
test=# select count(*) from test where test_volatile(id)=1;
count
-------
0
(1 row) Time: 39652.495 ms (00:39.652)
test=# select count(*) from test where test_stable(id)=1;
count
-------
0
(1 row) Time: 38789.952 ms (00:38.790)
test=# select count(*) from test where test_immutable(id)=1; count
-------
0
(1 row) Time: 38591.957 ms (00:38.592)
3、函数在等式右边的情况
test=# select count(*) from test where id=test_volatile(1);
count
-------
0
(1 row) Time: 40353.777 ms (00:40.354)
test=# select count(*) from test where id=test_stable(1);
count
-------
0
(1 row) Time: 40500.253 ms (00:40.500)
test=# select count(*) from test where id=test_immutable(1);
count
-------
0
(1 row) Time: 374.300 ms
4、传入常量值
可以看到,对于常量值,stable 和 immutable 类型的函数实际只需调用一次。
test=# select count(*) from test where test_volatile(1)=1;
count
-------
0
(1 row) Time: 41647.551 ms (00:41.648)
test=# select count(*) from test where test_stable(1)=1;
count
-------
0
(1 row) Time: 399.161 ms test=# select count(*) from test where test_immutable(1)=1;
count
-------
0
(1 row) Time: 389.367 ms
5、for循环
可以看到,对于相同的输入参数, test_immutable 在同一query 只执行一次。
对于for 循环,实际结果相同。
test=# begin
test-# for i in 1..100 loop
test-# perform test_immutable(1);
test-# end loop;
test-# end;
test-# /
ANONYMOUS BLOCK
Time: 1001.184 ms (00:01.001)
6、等式右边的函数属性也会影响索引的使用
来看以下例子:
test=# create table t2(id integer,name char(999));
CREATE TABLE ^
test=# insert into t2 select generate_series(1,100),repeat('a',999);
INSERT 0 100
test=# create index ind_t2 on t2(id);
CREATE INDEX
test=#
test=# analyze t2;
ANALYZE
test=# explain analyze select count(*) from t2 where id=test_volatile(1);
QUERY PLAN
-----------------------------------------------------------------------------------------------------------
Aggregate (cost=41.25..41.26 rows=1 width=8) (actual time=38735.427..38735.428 rows=1 loops=1)
-> Seq Scan on t2 (cost=0.00..41.25 rows=1 width=0) (actual time=38735.424..38735.425 rows=0 loops=1)
Filter: (id = test_volatile(1))
Rows Removed by Filter: 100
Planning Time: 0.191 ms
Execution Time: 38735.447 ms
(6 rows) test=# explain analyze select count(*) from t2 where id=test_stable(1);
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------
Aggregate (cost=8.41..8.42 rows=1 width=8) (actual time=385.449..385.450 rows=1 loops=1)
-> Index Only Scan using ind_t2 on t2 (cost=0.39..8.41 rows=1 width=0) (actual time=385.446..385.446 rows=0 loops=1)
Index Cond: (id = test_stable(1))
Heap Fetches: 0
Planning Time: 398.499 ms
Execution Time: 385.487 ms
(6 rows) test=# explain analyze select count(*) from t2 where id=test_immutable(1);
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------
Aggregate (cost=8.16..8.17 rows=1 width=8) (actual time=0.012..0.012 rows=1 loops=1)
-> Index Only Scan using ind_t2 on t2 (cost=0.14..8.16 rows=1 width=0) (actual time=0.011..0.011 rows=0 loops=1)
Index Cond: (id = '10000000'::bigint)
Heap Fetches: 0
Planning Time: 383.902 ms
Execution Time: 0.032 ms
(6 rows)
可以看到volatile 情况下,无法使用索引
四、oracle是怎么处理的?
SQL> create table test(id integer); Table created. SQL> insert into test select 1 from dba_objects where rownum<101; 100 rows created. create or replace function test_deterministic(id integer)
return integer
deterministic
as
cnt integer;
begin
for i in 1..10 loop
select count(*) into cnt from t1 ;
end loop;
return cnt;
end ; create or replace function test_volatile(id integer)
return integer
as
cnt integer;
begin
for i in 1..10 loop
select count(*) into cnt from t1 ;
end loop;
return cnt;
end ;
测试结果如下:
SQL> select * from test where id=test_volatile(1);
no rows selected
Elapsed: 00:00:50.50 SQL> select * from test where id=test_deterministic(1);
no rows selected
Elapsed: 00:00:01.04 SQL> select * from test where test_volatile(id)=1;
no rows selected
Elapsed: 00:00:50.56 --这个与KingbaseES 不同,只需调用一次
SQL> select * from test where test_deterministic(id)=1;
no rows selected
Elapsed: 00:00:01.02 --这个与KingbaseES 不同,只需调用一次
SQL> select * from test where test_volatile(1)=1;
no rows selected
Elapsed: 00:00:00.51 SQL> select * from test where test_deterministic(1)=1;
no rows selected
Elapsed: 00:00:00.52
KingbaseES 与Oracle 函数稳定性对于性能影响差异比较的更多相关文章
- KingbaseES 函数稳定性与SQL性能
背景:客户现场的一次艰苦的调优过程(https://www.cnblogs.com/kingbase/p/16015834.html),让我觉得非常有必要让数据库用户了解函数的不同稳定性属性,及其对于 ...
- 痞子衡嵌入式:简析i.MXRT1170 Cortex-M7 FlexRAM ECC功能特点、开启步骤、性能影响
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是恩智浦i.MXRT1170上Cortex-M7内核的FlexRAM ECC功能. ECC是"Error Correcting ...
- 痞子衡嵌入式:简析i.MXRT1170 Cortex-M4 L-MEM ECC功能特点、开启步骤、性能影响
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是恩智浦i.MXRT1170上Cortex-M4内核的L-MEM ECC功能. 本篇是 <简析i.MXRT1170 Cortex-M ...
- 盘点 Oracle 11g 中新特性带来的10大性能影响
Oracle的任何一个新版本,总是会带来大量引人瞩目的新特性,但是往往在这些新特性引入之初,首先引起的是一些麻烦,因为对于新技术的不了解.因为对于旧环境的不适应,从Oracle产品到技术服务运维,总是 ...
- 如何让Oracle数据库保持优良性能的方法
OracleDatabase,又名OracleRDBMS,或简称Oracle.是甲骨文公司的一款关系数据库管理系统.它是在数据库领域一直处于领先地位的产品.可以说Oracle数据库系统是目前世界上流行 ...
- 万级K8s集群背后etcd稳定性及性能优化实践
背景与挑战 随着腾讯自研上云及公有云用户的迅速增长,一方面,腾讯云容器服务TKE服务数量和核数大幅增长, 另一方面我们提供的容器服务类型(TKE托管及独立集群.EKS弹性集群.edge边缘计算集群.m ...
- 万级K8s集群背后 etcd 稳定性及性能优化实践
1背景与挑战随着腾讯自研上云及公有云用户的迅速增长,一方面,腾讯云容器服务TKE服务数量和核数大幅增长, 另一方面我们提供的容器服务类型(TKE托管及独立集群.EKS弹性集群.edge边缘计算集群.m ...
- ToList<>()所带来的性能影响
ToList<>()所带来的性能影响 前几天优化师弟写的代码,有一个地方给我留下很深刻的印象,就是我发现他总是将PLINQ的结果ToList<>(),然后再返回给主程序,对于 ...
- oracle函数操作
感于总有些网友提出一些非常基础的问题,比如有没有实现某某功能的函数啊,某某函数是做什么用的啊,格式是什么等等,同时也感受到自己对oracle函数认识的不足,于是集中月余时间专注于oracle函数,小有 ...
随机推荐
- gitlab备份迁移与升级
升级计划: https://docs.gitlab.com/ee/update/index.html#upgrade-paths 1. 安装gitlab(和源版本必须保持一致) wget https: ...
- expect自动应答
expect脚本 1. expect简介 expect是一个用来处理交互的命令.借助Expect,我们可以将交互过程写在一个脚本上,使之自动化完成. expect(自动应答) 基于TCL(Tool C ...
- Mybatis中@select注解联合查询
前言 在项目中经常会使用到一些简单的联合查询获取对应的数据信息,我们常规都是会根据对应的mapper接口写对应的mapper.xml的来通过对应的业务方法来调用获取,针对这一点本人感觉有点繁琐,就对@ ...
- 【Java面试】什么是 ISR,为什么需要引入 ISR
Hi,大家好,我是Mic. 一个工作5年的粉丝,在简历上写精通Kafka. 结果在面试的时候直接打脸. 面试官问他:"什么是ISR,为什么需要设计ISR" 然后他一脸懵逼的看着面试 ...
- org/apache/poi/POIXMLTypeLoader或者java.lang.NoSuchFieldError: RETURN_NULL_AND_BLANK
原因是之前我的poi和ooxml版本有点低, 解决方案 将两者版本提高,我是将两者的版本都提高到了3.15
- React key究竟有什么作用?深入源码不背概念,五个问题刷新你对于key的认知
壹 ❀ 引 我在[react]什么是fiber?fiber解决了什么问题?从源码角度深入了解fiber运行机制与diff执行一文中介绍了react对于fiber处理的协调与提交两个阶段,而在介绍协调时 ...
- JetBrains系列IDE创建文件模板
#coding:utf-8 ''' @version: python3.6 @author: '$USER' @license: Apache Licence @contact: steinven@q ...
- JS计算文本字符串字节长度和像素长度的方法
来源:js获取字符长度并计算px宽度 - [云]风过无痕 - 博客园 (cnblogs.com) <!DOCTYPE html> <html lang="en"& ...
- Odoo14 rpc
odoo14中rpc调用分为两种. 一种是外部调用rpc来访问odoo数据,这个时候你需要登录授权. 另一种是我们自己编写的widget小部件或者自定义视图时候通过js通过rpc去获取数据. 这里说的 ...
- Java学习(三)Java起源&发展
目录 Java的诞生 C&C++ Java初生 Java发展(三高: 高可用,高性能,高并发) Java特性和劣势 Java程序运行机制 Java的诞生 C&C++ **1972年 ...