Oracle 与 PostgreSQL 函数行为的差异引发性能差异
对于Oracle,对于数据修改的操作通过存储过程处理,而对于函数一般不进行数据修改操作。同时,函数可以通过 Select 进行调用,而存储过程则不行。
一、对于volatile 函数的行为
1、Oracle 行为
创建函数:
create or replace function fun01 return number as
begin
insert into t1 values(1);
return 1;
end; create or replace function fun02 return number as
v_cnt number;
begin
select count(*) into v_cnt from t1;
return v_cnt;
end;
(1)、函数有修改操作,不允许select 调用
有修改操作,不允许 select 调用:
SQL> select fun01() from dual;
select fun01() from dual
*
ERROR at line 1:
ORA-14551: cannot perform a DML operation inside a query
ORA-06512: at "SYS.FUN01", line 3
没有修改操作,可以select 调用:
SQL> select fun02() from dual; FUN02()
----------
2
有修改操作的函数,只能通过call 调用
SQL> var a number;
SQL> call fun01() into :a; Call completed.
(2)、视图包含函数的情景
create or replace view v_t2 as select id, fun01() as t1_cnt from t2; test=# select count(*) from v_t2;
count
-------
2
(1 row)
经验证,虽然 fun01 含有 insert 操作,但实际函数(fun01)是没有调用的,也就是函数内的 insert 没有执行。这个个人理解应该是个不严谨的地方。
2、PostgreSQL 行为
创建函数:
create or replace function fun01() returns number as
$$
begin
insert into t1 values(1);
return 1;
end;
$$
language plpgsql;
(1)、函数有修改操作,可以通过Select 调用
test=# select count(*) from t1;
count
-------
3
(1 row) test=# select fun01();
fun01
-------
1
(1 row) test=# select count(*) from t1;
count
-------
4
(1 row)
(3)、视图包含函数的情景
create or replace view v_t2 as select id, fun01() as t1_cnt from t2; test=# select count(*) from v_t2;
count
-------
2
(1 row)
经验证,查询视图时,针对每一行,都会调用fun01 函数一次,也就是 insert 操作实际发生的。
二、对于Stable函数的行为
以上的例子中,由于函数含有insert 操作,因此,函数只能是 volatile。 如果函数是 stable or immutable,那又是何种现象了?
构建数据: t1 表的数据量比较大,count(*) 一次大概要2秒
test=# create table t1(id integer,name text);
CREATE TABLE
test=# create table t2(id integer);
CREATE TABLE insert into t1 select generate_series(1,50000000),'a';
insert into t2 select generate_series(1,10); test=# select count(*) from t1;
count
----------
50000000
(1 row) Time: 2059.901 ms (00:02.060)
创建函数与视图
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 $$ ;
/ create view v_t2_volatile as select id,test_volatile(1) from t2;
create view v_t2_stable as select id,test_stable(1) from t2;
create view v_t2_immutable as select id,test_immutable(1) from t2;
验证视图的访问效率:immutable or stable 类型的函数实际一次都没有执行。
test=# select count(*) from v_t2_immutable;
count
-------
10
(1 row) Time: 1.027 ms test=# select count(*) from v_t2_stable;
count
-------
10
(1 row) Time: 0.950 ms
test=# select count(*) from v_t2_volatile;
count
-------
10
(1 row) Time: 23231.599 ms (00:23.232)
三、性能“问题”
对于 select count(*) from v_t2 (视图),由于 oracle 并不执行函数 ,因此,性能肯定更快。而对于 postgresql,针对每条都要调用一次函数,性能上肯定更慢。
Oracle 与 PostgreSQL 函数行为的差异引发性能差异的更多相关文章
- MySQL&SQL server&Oracle&Access&PostgreSQL数据库sql注入详解
判断数据库的类型 当我们通过一些测试,发现存在SQL注入之后,首先要做的就是判断数据库的类型. 常用的数据库有MySQL.Access.SQLServer.Oracle.PostgreSQL.虽然绝大 ...
- oracle VS postgresql系列-行列转换
[需求]例如先有数据为 id | name ------+--------- | lottu | xuan | rax | ak | vincent 现在需要转换为 id | names ------ ...
- postgresql 函数 参数为复合类型
postgresql没有存储过程,但是函数功能很强大. 在近期开发的电商管理平台中,对于产品的类目管理,设计时有个属性字段,设为字符数组,但是EF不支持数组的操作,所以在添加和修改类目时,需要对属性的 ...
- ORACLE当中自定义函数性优化浅析
为什么函数影响性能 在SQL语句中,如果不合理的使用函数(Function)就会严重影响性能,其实这里想说的是PL/SQL中的自定义函数,反而对于一些内置函数而言,影响性能的可能性较小.那么为什么SQ ...
- [转载]ORACLE日期时间函数大全
ORACLE日期时间函数大全 TO_DATE格式(以时间:2007-11-02 13:45:25为例) Year: yy two digits 两位年 ...
- Oracle的pipelined函数实现高性能大数据处理
从Oracle 8开始,我们就可以从一个collection类型的数据集合中查询出数据,这个集合称之为"虚拟表".它的方法是"SELECT FROM TABLE(CAST ...
- 【转帖】从 Oracle 到 PostgreSQL ,某保险公司迁移实践 技术实践
从 Oracle 到 PostgreSQL ,某保险公司迁移实践 http://www.itpub.net/2019/11/08/4108/ 信泰人寿保险股份有限公司 摘要:去O一直是金融保险行业永恒 ...
- Oracle 与 postgreSQL 事务处理区别(多版本与undo区别)
2015年左右,因为工作需要用MongoDB.CouchBase这两种文档型数据库,时不时到这两个数据库官网上查资料.报BUG.时常可以在MongoDB官网上看到这样一些新闻,“某某企业成功将MySQ ...
- Sql获取表所有列名字段——select * 替换写法,Sqlserver、Oracle、PostgreSQL、Mysql
实际开发中经常用到select * from table,往往需要知道具体的字段,这个时候再去数据库中翻或者查看数据字典比较麻烦.为了方便,自己特意写了一个小函数f_selectall,针对SqlSe ...
随机推荐
- 《Java编程思想》学习笔记_多态
多态 多态指一个行为产生多种状态,针对父类类型可接收其子类类型,最终执行的状态由具体子类确定,其不同子类可呈现出不同状态.例如人[父类]都会跑步[行为],但小孩[子类]跑步.成年人[子类]跑步.运动员 ...
- bat-winget-win平台的软件包管理器
win10 1709版本以后 引入的包管理器,如果不可用 需要 更新一下 应用安装程序. winget命令的功能 常用的就 安装 卸载 更新 . 卸载 使用中如果提示 策略 不允许,可执行下面命 ...
- NC14247 Xorto
NC14247 Xorto 题目 题目描述 给定一个长度为 \(n\) 的整数数组,问有多少对互不重叠的非空区间,使得两个区间内的数的异或和为 \(0\) . 输入描述 第一行一个数 \(n\) 表示 ...
- 如何将 DevSecOps 引入企业?
前 言 现如今,大部分企业已经在内部实现了 DevOps 实践.DevOps 为团队提供了交付可靠软件和快速更新的方法论.这种方法让团队更专注于质量而不是将时间浪费在运维上.然而,结果是,安全实践往往 ...
- Tapdata x 轻流,为用户打造实时接入轻流的数据高速通道
在全行业加速布局数字化的当口,如何善用工具,也是为转型升级添薪助力的关键一步. 那么当轻量的异构数据实时同步工具,遇上轻量的数字化管理工具,将会收获什么样的新体验?此番 Tapdata 与轻流 ...
- Linux操作系统(7):rpm包管理和yum软件包在线管理
一.rpm 包的管理 介绍:一种用于互联网下载包的打包及安装工具,它包含在某些 Linux 分发版中.它生成具有.RPM 扩展名的文件.RPM 是 RedHat Package Manager(Red ...
- 【一知半解】synchronied
synchronized是什么 synchronized是java同步锁,同一时刻多个线程对同一资源进行修改时,能够保证同一时刻只有一个线程获取到资源并对其进行修改,因此保证了线程安全性. synch ...
- 没有编辑器时,使用echo更换源
echo "\ deb http://mirrors.aliyun.com/ubuntu/ xenial main deb-src http://mirrors.aliyun.com/ubu ...
- python--函数参数传递
1. 调用函数时,实参会传递给形参,叫做参数传递. 2. 根据实际参数的类型不同,函数参数的传递方式可分为 2 种,分别为值传递和引用(地址)传递: 值传递:传递的实参类型为不可变类型(字符串.数字. ...
- 转:mysql保留关键字
原文链接:http://www.tuicool.com/articles/Brauq2e 从网上找了一个mysql的保留字列表,仅供参考. ADD ALL ALTER ANALYZE AND AS A ...