金仓数据库KingbaseES immutable 与 stable 函数的差异
创始人
2024-03-07 03:10:26
0

目录

1、准备数据

2、创建immutable 和 stable 函数

3、单独explain 函数

4、例子一

5、例子二


Stable 函数不能修改数据库,单个Query中所有行给定同样的参数确保返回相同的结果。这种稳定级别允许优化器将多次函数调用转换为一次。在索引扫描的条件中使用这种函数是可行的,因为索引扫描只计算一次比较值(comparison value),而不是每行都计算一次。

Immutable 函数不能修改数据库,在任何情况下,只要输入参数相同,返回结果就相同。这种级别的函数,优化器可以提前进行计算,在查询过程中作为常量参数。比如:SELECT...WHERE x=2+2 可以简化为SELECT...WHERE x=4。

以下以例子说明二者的差异。

1、准备数据

create table t1(id1 integer,id2 integer);
insert into t1 select generate_series(1,10000000),generate_series(1,10000000);
test=# \timing on
Timing is on.
test=# select count(*) from t1;count
----------10000000
(1 row)
Time: 681.445 ms

2、创建immutable 和 stable 函数

create or replace function f001()returns bigintimmutablelanguage sql
as
$$ select count(*) from t1 $$ ;
create or replace function f002()returns bigintstablelanguage sql
as
$$ select count(*) from t1 $$ ;

3、单独explain 函数

可以看到对于 immutable 函数,在 explain 时,实际会去执行的;而stable 函数,explain 时则不会实际执行。

test=# explain select f001();QUERY PLAN
------------------------------------------Result  (cost=0.00..0.01 rows=1 width=8)
(1 row)
Time: 450.572 ms
test=# explain select f002();QUERY PLAN
------------------------------------------Result  (cost=0.00..0.26 rows=1 width=8)
(1 row)
Time: 0.641 ms 
test=# select f001();f001
----------10000000
(1 row)
Time: 448.720 ms
test=# select f002();f002
----------10000000
(1 row)
Time: 426.745 ms

4、例子一

可以看到 immutable 函数执行时间主要花在planning上,也就是在制定执行计划前,就已经取得函数的值;而 stable 函数,则在语句解析和执行时,都要执行函数,而且,针对语句的访问的每个tuple,都要执行一次函数调用。

test=# explain analyze select * from (select * from t1 limit 10) a where a.id1=f001();QUERY PLAN
---------------------------------------------------------------------------------------------------------------------Subquery Scan on a  (cost=0.00..0.27 rows=1 width=8) (actual time=0.012..0.013 rows=0 loops=1)Filter: (a.id1 = '10000000'::bigint)Rows Removed by Filter: 10->  Limit  (cost=0.00..0.15 rows=10 width=8) (actual time=0.009..0.010 rows=10 loops=1)->  Seq Scan on t1  (cost=0.00..148609.21 rows=10007621 width=8) (actual time=0.008..0.009 rows=10 loops=1)Planning Time: 413.963 msExecution Time: 0.026 ms
(7 rows)test=# explain analyze select * from (select * from t1 limit 10) a where a.id1=f002();QUERY PLAN
---------------------------------------------------------------------------------------------------------------------Subquery Scan on a  (cost=0.00..2.77 rows=1 width=8) (actual time=3691.788..3691.788 rows=0 loops=1)Filter: (a.id1 = f002())Rows Removed by Filter: 10->  Limit  (cost=0.00..0.15 rows=10 width=8) (actual time=0.012..0.028 rows=10 loops=1)->  Seq Scan on t1  (cost=0.00..148609.21 rows=10007621 width=8) (actual time=0.011..0.021 rows=10 loops=1)Planning Time: 364.233 msExecution Time: 3691.807 ms
(7 rows)Time: 4056.907 ms (00:04.057)test=# explain analyze select * from (select * from t1 where 1=2) a where a.id1=f002();QUERY PLAN
------------------------------------------------------------------------------------------Result  (cost=0.00..2675533.51 rows=1 width=8) (actual time=0.001..0.001 rows=0 loops=1)One-Time Filter: false->  Seq Scan on t1  (cost=0.00..2675533.51 rows=1 width=8) (never executed)Filter: (id1 = f002())Planning Time: 490.720 msExecution Time: 0.017 ms
(6 rows)test=# explain analyze select * from (select * from t1 limit 1) a where a.id1=f002();QUERY PLAN
--------------------------------------------------------------------------------------------------------------------Subquery Scan on a  (cost=0.00..0.28 rows=1 width=8) (actual time=390.833..390.834 rows=0 loops=1)Filter: (a.id1 = f002())Rows Removed by Filter: 1->  Limit  (cost=0.00..0.01 rows=1 width=8) (actual time=0.024..0.053 rows=1 loops=1)->  Seq Scan on t1  (cost=0.00..148609.21 rows=10007621 width=8) (actual time=0.023..0.023 rows=1 loops=1)Planning Time: 426.693 msExecution Time: 390.852 ms
(7 rows)

5、例子二

sysdate 函数 为 stable 时:sysdate 函数在同一事务内多次执行返回的结果都相同,跨事务则每次结果不同。

test=# begin
test-#   for i in 1..5 loop
test-#     raise notice '%', sysdate();
test-#     perform sys_sleep(1);
test-#     commit;
test-#   end loop;
test-# end;
test-# /
NOTICE:  2022-06-29 19:53:18
NOTICE:  2022-06-29 19:53:19
NOTICE:  2022-06-29 19:53:20
NOTICE:  2022-06-29 19:53:21
NOTICE:  2022-06-29 19:53:22
ANONYMOUS BLOCK
Time: 5011.031 ms (00:05.011)
test=# begin
test-#   for i in 1..5 loop
test-#     raise notice '%', sysdate();
test-#     perform sys_sleep(1);
test-#   end loop;
test-# end;
test-# /
NOTICE:  2022-06-29 19:54:14
NOTICE:  2022-06-29 19:54:14
NOTICE:  2022-06-29 19:54:14
NOTICE:  2022-06-29 19:54:14
NOTICE:  2022-06-29 19:54:14
ANONYMOUS BLOCK
Time: 5005.724 ms (00:05.006)

sysdate 函数为 immutable 时:不管是否跨事务,sysdate 函数结果都相同。

test=# alter function sysdate immutable;
ALTER FUNCTION
Time: 6.276 ms
test=# begin test-# for i in 1..5 loop test-# raise notice '%', sysdate(); test-# perform sys_sleep(1); test-# commit; test-# end loop; test-# end; test-# / NOTICE: 2022-06-29 19:54:58 NOTICE: 2022-06-29 19:54:58 NOTICE: 2022-06-29 19:54:58 NOTICE: 2022-06-29 19:54:58 NOTICE: 2022-06-29 19:54:58 ANONYMOUS BLOCK Time: 5007.899 ms (00:05.008)
test=# begin test-# for i in 1..5 loop test-# raise notice '%', sysdate(); test-# perform sys_sleep(1); test-# end loop; test-# end; test-# / NOTICE: 2022-06-29 19:55:11 NOTICE: 2022-06-29 19:55:11 NOTICE: 2022-06-29 19:55:11 NOTICE: 2022-06-29 19:55:11 NOTICE: 2022-06-29 19:55:11 ANONYMOUS BLOCK Time: 5007.694 ms (00:05.008)

 

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWR报告解读 WORKLOAD REPOSITORY PDB report (PDB snapshots) AW...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
群晖外网访问终极解决方法:IP... 写在前面的话 受够了群晖的quickconnet的小水管了,急需一个新的解决方法&#x...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
Azure构建流程(Power... 这可能是由于配置错误导致的问题。请检查构建流程任务中的“发布构建制品”步骤,确保正确配置了“Arti...