一、函数的属性

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 函数稳定性对于性能影响差异比较的更多相关文章

  1. KingbaseES 函数稳定性与SQL性能

    背景:客户现场的一次艰苦的调优过程(https://www.cnblogs.com/kingbase/p/16015834.html),让我觉得非常有必要让数据库用户了解函数的不同稳定性属性,及其对于 ...

  2. 痞子衡嵌入式:简析i.MXRT1170 Cortex-M7 FlexRAM ECC功能特点、开启步骤、性能影响

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是恩智浦i.MXRT1170上Cortex-M7内核的FlexRAM ECC功能. ECC是"Error Correcting ...

  3. 痞子衡嵌入式:简析i.MXRT1170 Cortex-M4 L-MEM ECC功能特点、开启步骤、性能影响

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是恩智浦i.MXRT1170上Cortex-M4内核的L-MEM ECC功能. 本篇是 <简析i.MXRT1170 Cortex-M ...

  4. 盘点 Oracle 11g 中新特性带来的10大性能影响

    Oracle的任何一个新版本,总是会带来大量引人瞩目的新特性,但是往往在这些新特性引入之初,首先引起的是一些麻烦,因为对于新技术的不了解.因为对于旧环境的不适应,从Oracle产品到技术服务运维,总是 ...

  5. 如何让Oracle数据库保持优良性能的方法

    OracleDatabase,又名OracleRDBMS,或简称Oracle.是甲骨文公司的一款关系数据库管理系统.它是在数据库领域一直处于领先地位的产品.可以说Oracle数据库系统是目前世界上流行 ...

  6. 万级K8s集群背后etcd稳定性及性能优化实践

    背景与挑战 随着腾讯自研上云及公有云用户的迅速增长,一方面,腾讯云容器服务TKE服务数量和核数大幅增长, 另一方面我们提供的容器服务类型(TKE托管及独立集群.EKS弹性集群.edge边缘计算集群.m ...

  7. 万级K8s集群背后 etcd 稳定性及性能优化实践

    1背景与挑战随着腾讯自研上云及公有云用户的迅速增长,一方面,腾讯云容器服务TKE服务数量和核数大幅增长, 另一方面我们提供的容器服务类型(TKE托管及独立集群.EKS弹性集群.edge边缘计算集群.m ...

  8. ToList<>()所带来的性能影响

    ToList<>()所带来的性能影响  前几天优化师弟写的代码,有一个地方给我留下很深刻的印象,就是我发现他总是将PLINQ的结果ToList<>(),然后再返回给主程序,对于 ...

  9. oracle函数操作

    感于总有些网友提出一些非常基础的问题,比如有没有实现某某功能的函数啊,某某函数是做什么用的啊,格式是什么等等,同时也感受到自己对oracle函数认识的不足,于是集中月余时间专注于oracle函数,小有 ...

随机推荐

  1. tomcat 的安全配置预防后台被攻击

    安全是系统架构中最重要的关注点之一,通常情况下,所说的安全涵盖网络安全.数据安全.操作系统安全.服务器安全以及应用系统安全等诸多方面. Tomcat 是一个免费的开放源代码 的Web应用服务器,技术先 ...

  2. ShardingSphere-proxy-5.0.0建立mysql读写分离的连接(六)

    一.修改配置文件config-sharding.yaml,并重启服务 # # Licensed to the Apache Software Foundation (ASF) under one or ...

  3. windows下telnet的用法

    前言 这里利用Windows7下如何使用Telnet命令给大家总结如下: 第一步:在控制面板里,点击"程序"选项 第二步:在程序选项下,点击"打开或关闭Windows功能 ...

  4. 通过Go语言创建CA与签发证书

    本篇文章中,将描述如何使用go创建CA,并使用CA签署证书.在使用openssl创建证书时,遵循的步骤是 创建秘钥 > 创建CA > 生成要颁发证书的秘钥 > 使用CA签发证书.这种 ...

  5. 面向个性化需求的在线云数据库混合调优系统 | SIGMOD 2022入选论文解读

    SIGMOD 数据管理国际会议是数据库领域具有最高学术地位的国际性会议,位列数据库方向顶级会议之首.近日,腾讯云数据库团队的最新研究成果入选 SIGMOD 2022 Research Full Pap ...

  6. Overfitting & Train Set & Test Set

    假设数据集是独立同分布的,可以将数据集划分为不同的比例:Train Set and Test Set. 同时在Train Set and Test Set上做精度测试,或者隔一段时间在Test Set ...

  7. 用Bootstrap4写了一个WordPress主题Writing

    这是一个简洁的WordPress博客主题,为专注写作而设计. 本主题使用Bootstrap4框架开发. 主要功能 自适应: 标签云页面模板: 两栏设计: 全宽页面模板: 支持设置背景色和背景图片: 8 ...

  8. 2019 CSP-S 初赛解析

    因为我不会设置用博客园显示Markdown语法,所以在洛谷也写了一份:传送门 一起讨论的这套卷.题干 然后还有一些可以借鉴一下的解析 选择: T1. 注意运算顺序: a%3=1 --> (int ...

  9. .NET(C#)发送邮件的实现方法

    .NET(C#)发送邮件的实现方法 微软已经为我们准备好了现成的工具类供我们调用: MailMessage //邮件信息类 SmtpClient //邮件发送类 首先需要在项目的类文件中引用以下命名空 ...

  10. springboot配置logback.xml

    由于springboot框架自带log4j,因此我们只需配置下logback文件,即可, 在main/resources根目录下,新建logback-spring.xml文件,copy下述代码: &l ...