对于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 函数行为的差异引发性能差异的更多相关文章

  1. MySQL&SQL server&Oracle&Access&PostgreSQL数据库sql注入详解

    判断数据库的类型 当我们通过一些测试,发现存在SQL注入之后,首先要做的就是判断数据库的类型. 常用的数据库有MySQL.Access.SQLServer.Oracle.PostgreSQL.虽然绝大 ...

  2. oracle VS postgresql系列-行列转换

    [需求]例如先有数据为 id | name ------+--------- | lottu | xuan | rax | ak | vincent 现在需要转换为 id | names ------ ...

  3. postgresql 函数 参数为复合类型

    postgresql没有存储过程,但是函数功能很强大. 在近期开发的电商管理平台中,对于产品的类目管理,设计时有个属性字段,设为字符数组,但是EF不支持数组的操作,所以在添加和修改类目时,需要对属性的 ...

  4. ORACLE当中自定义函数性优化浅析

    为什么函数影响性能 在SQL语句中,如果不合理的使用函数(Function)就会严重影响性能,其实这里想说的是PL/SQL中的自定义函数,反而对于一些内置函数而言,影响性能的可能性较小.那么为什么SQ ...

  5. [转载]ORACLE日期时间函数大全

    ORACLE日期时间函数大全 TO_DATE格式(以时间:2007-11-02   13:45:25为例)           Year:              yy two digits 两位年 ...

  6. Oracle的pipelined函数实现高性能大数据处理

    从Oracle 8开始,我们就可以从一个collection类型的数据集合中查询出数据,这个集合称之为"虚拟表".它的方法是"SELECT FROM TABLE(CAST ...

  7. 【转帖】从 Oracle 到 PostgreSQL ,某保险公司迁移实践 技术实践

    从 Oracle 到 PostgreSQL ,某保险公司迁移实践 http://www.itpub.net/2019/11/08/4108/ 信泰人寿保险股份有限公司 摘要:去O一直是金融保险行业永恒 ...

  8. Oracle 与 postgreSQL 事务处理区别(多版本与undo区别)

    2015年左右,因为工作需要用MongoDB.CouchBase这两种文档型数据库,时不时到这两个数据库官网上查资料.报BUG.时常可以在MongoDB官网上看到这样一些新闻,“某某企业成功将MySQ ...

  9. Sql获取表所有列名字段——select * 替换写法,Sqlserver、Oracle、PostgreSQL、Mysql

    实际开发中经常用到select * from table,往往需要知道具体的字段,这个时候再去数据库中翻或者查看数据字典比较麻烦.为了方便,自己特意写了一个小函数f_selectall,针对SqlSe ...

随机推荐

  1. ABAP CDS - DEFINE VIEW, name_list

    Syntax ... ( name1, name2, ... ) ... Effect Defines the element names of a CDS view in ABAP CDS in a ...

  2. 揭秘GaussDB(for Redis):全面对比Codis

    摘要:Codis集群在国内Redis生态圈很流行,社区已停止维护.本文从架构和特性两方面对比,带你感受华为云GaussDB(for Redis)的全新价值. 本文分享自华为云社区<华为云Gaus ...

  3. Redis docker 主从模式与哨兵sentinel

    更多技术记录,请参考软件开发 | 编程 | RustFisher 为实现redis的高可用,我们采用主从模式加哨兵的方法. 一主二从三哨兵,共启动6个redis容器.本文示例在同一个服务器上进行操作. ...

  4. 项目: ATM+购物车

    ATM+购物车 项目文件: 介绍 以下为文件夹层次和内容: readme.md 1. 需求 模拟银行取款 + 购物全过程 1.注册 2.登录 3.提现 4.还款 5.转账 6.查看余额 7.查看购物车 ...

  5. leetcode教程系列——Binary Tree

    tree是一种常用的数据结构用来模拟真实物理世界里树的层级结构.每个tree有一个根(root)节点和指向其他节点的叶子(leaf)节点.从graph的角度看,tree也可以看作是有N个节点和N-1个 ...

  6. 今天介绍一下自己的开源项目,一款以spring cloud alibaba为核心的微服务架构项目,为给企业与个人提供一个零开发基础的微服务架构。

    LaoCat-Spring-Cloud-Scaffold 一款以spring cloud alibab 为核心的微服务框架,主要目标为了提升自己的相关技术,也为了给企业与个人提供一个零开发基础的微服务 ...

  7. C++类中的常成员和静态成员

    常变量.常对象.常引用.指向常对象或常变量的指针等在定义时都使用了const关键字,这是C++语言引入的一种数据保护机制,称为const数据保护机制.例如通过const关键字主动地将被调函数形参进行限 ...

  8. NOI / 1.4编程基础之逻辑表达式与条件分支讲解-02:输出绝对值

    02:输出绝对值 总时间限制: 1000ms 内存限制: 65536kB 题目: 描述 输入一个浮点数,输出这个浮点数的绝对值. 输入 输入一个浮点数,其绝对值不超过10000. 输出 输出这个浮点数 ...

  9. 零基础学Java(10)面向对象-使用LocalDate类完成日历设计

    前言 在我们完成这个日历设计前,需要了解Java中的预定义类LocalDate的一些用法 语法 LocalDate.now() // 2022-07-01 会构造一个新对象,表示构造这个对象时的日期. ...

  10. 基于.NetCore开发博客项目 StarBlog - (16) 一些新功能 (监控/统计/配置/初始化)

    系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...