Oracle的pipelined函数实现高性能大数据处理
从Oracle 8开始,我们就可以从一个collection类型的数据集合中查询出数据,这个集合称之为“虚拟表“。它的方法是“SELECT FROM TABLE(CAST(plsql_function AS collection_type))”,据说该方法在处理大数据量时会有内存方面的限制。到了Oracle 9i之后,一个称为pipelined表函数的技术被推出来。他和普通的表函数很类似,但还有有一些显著的差别。
第一,pipelined函数处理的数据,是以管道的方式,或者说是流的方式从预先准备的小数组中展现给用户,而普通表函数将数据全部准备好再展现给用户。
第二,pipelined函数可以并发,这意味着PLSQL可以同一时间在多个进程上执行。
第三,pipelined函数可以很容易将存储过程转换成用bulk操作的行,有利于实现的复杂转换逻辑的SQL。
(miki西游 @mikixiyou 原文链接: http://mikixiyou.iteye.com/blog/1628397 )
了解pipelined函数的最佳方法是看一个简单的例子。对于任何一个pipelined函数,都必须有两点要求。
1、一个定义在模式中或者包中collection类型;
2、一个单独的PL/SQL函数或一个包中的函数,函数的返回类型后面必须加pipelined关键字;
在下面的例子中,我们将创建一个简单的pipelined函数,输出若干行记录。首先需要一个collection类型,用于格式化输出。
- CREATE OR REPLACE TYPE number_ntt AS TABLE OF NUMBER;
Oracle会使用这个类型缓存少量的记录作为pipelined函数调用时的输出。我们创建一个简单的pipelined函数。
- CREATE OR REPLACE FUNCTION row_generator(rows_in IN PLS_INTEGER)
- RETURN number_ntt PIPELINED
- IS
- BEGIN
- FOR i IN 1 .. rows_in LOOP
- PIPE ROW(i);
- END LOOP;
- RETURN;
- END;
在这个SQL中:
在函数定义部分的关键字pipelined是pipelined函数定义的关键,返回的类型必须是事先定义的collection类型,如这里是number_tt。
在函数主体部分的”PIPE ROW”是将一个单行记录写入到collection流中。记录中所有字段的类型必须和collection类型中所有字段匹配。
在函数主体部分的“return“的值是一个空值,而不是有任何符合collection类的值。
这些就是pipelined函数定义时需要严格遵守的规则。
现在已经创建好一个pipelined函数,我们可以测试一下。
- SQL> select * from TABLE( row_generator(10) );
- COLUMN_VALUE
- ------------
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 10 rows selected
将pipelined函数row_generator放到一个“TABLE”操作符中,虚拟成一个数据源,类似表或视图。这里虚拟表只有一个字段,名称“COLUMN_VALUE“是其默认值。更复杂的输出则需要将collection定义得更复杂些,使用到object或者record。
我们通过一个例子比较一下pipelined函数或普通的表函数在返回collection时有何差异。
第一步,创建普通的表函数,返回colletion类型。
- CREATE OR REPLACE FUNCTION table_function RETURN number_ntt AS
- nt number_ntt := number_ntt();
- BEGIN
- FOR i IN 1 .. 500000 LOOP
- if (mod(i, 10000) = 0) then
- nt.EXTEND;
- nt(nt.LAST) := i;
- end if;
- END LOOP;
- RETURN nt; --<-- return whole collection
- END table_function;
第二步,创建pipelined函数,返回的也是collection类型
- CREATE OR REPLACE FUNCTION pipelined_function RETURN number_ntt
- PIPELINED AS
- BEGIN
- FOR i IN 1 .. 500000 LOOP
- if (mod(i, 10000) = 0) then
- PIPE ROW(i); --<-- send row to consumer
- end if;
- END LOOP;
- RETURN;
- END pipelined_function;
函数的功能都是将能和1000整除的数字输出出来。
再创建一个输出时间到毫秒的函数,用于测试两个函数的输出特点。
- CREATE FUNCTION get_time RETURN TIMESTAMP IS
- BEGIN
- RETURN LOCALTIMESTAMP;
- END get_time;
- /
第三步,测试两个函数
测试普通函数如下:
- ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'HH24:MI:SS.FF3';
- SELECT get_time() AS ts FROM DUAL;
- SELECT column_value, get_time() AS ts FROM TABLE(table_function);
- SQL>
- TS
- --------------------------------------------------------------------------------
- 15:27:26.031
- COLUMN_VALUE TS
- ------------ --------------------------------------------------------------------------------
- 100000 15:27:26.218
- 200000 15:27:26.218
- 300000 15:27:26.218
- 400000 15:27:26.218
- 500000 15:27:26.218
- SQL>
结果显示,所有记录都是同一时间输出。
测试pipelined函数如下:
- SELECT get_time() AS ts FROM DUAL;
- SELECT column_value, get_time() AS ts FROM TABLE(pipelined_function);
- TS
- --------------------------------------------------------------------------------
- 15:27:26.265
- COLUMN_VALUE TS
- ------------ --------------------------------------------------------------------------------
- 100000 15:27:26.312
- 200000 15:27:26.343
- 300000 15:27:26.390
- 400000 15:27:26.421
- 500000 15:27:26.453
结果显示,所有记录都是逐次输出。
这点对于用户的UI太重要了。试想,如果执行一个查询,过了10秒钟才显示出所有的结果好,还是还是每秒都显示一些记录,知道10秒钟显示完毕好?
如果这个输出的结果集再放到到百万记录,两个函数对PGA内存的消耗又完全不一样,这点更重要。
Oracle的pipelined函数实现高性能大数据处理的更多相关文章
- 翻译-In-Stream Big Data Processing 流式大数据处理
相当长一段时间以来,大数据社区已经普遍认识到了批量数据处理的不足.很多应用都对实时查询和流式处理产生了迫切需求.最近几年,在这个理念的推动下,催生出了一系列解决方案,Twitter Storm,Yah ...
- [转载] 一共81个,开源大数据处理工具汇总(下),包括日志收集系统/集群管理/RPC等
原文: http://www.36dsj.com/archives/25042 接上一部分:一共81个,开源大数据处理工具汇总(上),第二部分主要收集整理的内容主要有日志收集系统.消息系统.分布式服务 ...
- 一共81个,开源大数据处理工具汇总(下),包括日志收集系统/集群管理/RPC等
作者:大数据女神-诺蓝(微信公号:dashujunvshen).本文是36大数据专稿,转载必须标明来源36大数据. 接上一部分:一共81个,开源大数据处理工具汇总(上),第二部分主要收集整理的内容主要 ...
- oracle的sql函数
只读事务set transaction read only当一个用户添加了只读事务,则查询时只会查到设置只读事务之前的内容,在并发量大的系统中,通过设置只读事务 便于统计 oracle的sql函数的使 ...
- [转]ORACLE日期时间函数大全
本文转自:http://www.cnblogs.com/chuncn/archive/2009/04/29/1381282.html ORACLE日期时间函数大全 TO_DATE格式(以时间: ::2 ...
- Spark大数据处理技术
全球首部全面介绍Spark及Spark生态圈相关技术的技术书籍 俯览未来大局,不失精细剖析,呈现一个现代大数据框架的架构原理和实现细节 透彻讲解Spark原理和架构,以及部署模式.调度框架.存储管理及 ...
- oracle的nvl函数的使用解析
Oracle的Nvl函数 nvl( ) 函数 从两个表达式返回一个非null 值. 语法 NVL(eExpression1, eExpression2) 参数 eExpression1, eExpre ...
- Oracle/Mysql/SqlServer函数区别
mysql日期和时间格式转换 Linux scp 使用详解 Oracle/Mysql/SqlServer函数区别 2011-07-01 12:34:36| 分类: Mysql技术 | 标签:mys ...
- 0基础搭建Hadoop大数据处理-初识
在互联网的世界中数据都是以TB.PB的数量级来增加的,特别是像BAT光每天的日志文件一个盘都不够,更何况是还要基于这些数据进行分析挖掘,更甚者还要实时进行数据分析,学习,如双十一淘宝的交易量的实时展示 ...
随机推荐
- Jmeter接口测试-基于nodejs的to do list项目说明
一.了解测试项目 我们的测试项目叫做smile_task,简称sm_task.这是一个基于nodejs超简单的todo list. 它的主要流程就是:输入标题描述---点击创建一个任务---编辑修改任 ...
- Selenium如何定位动态id/class的元素?
今天再给大家分享一个定位不到元素的原因——动态id. 没有打开新页面.没有alert.没有frame.加了等待时间,但是还是定位不到元素?很有可能是你要定位的元素的属性是动态的,即每次打开页面,这个 ...
- OpenGL绘图框架(GLFW)
下载地址:http://www.glfw.org/download.html
- 注入学习1:SQL注入语句大全
学习背景 之前做了xss预防,以及些许的注入预防了,但是不够全面,如果还是搜集了下一些常用的注入手段,以此用来进行更好的预防. 什么是注入 一般来说,SQL注入一般存在于形如:HTTP://xxx.x ...
- 安装vmtools Error: Unable to execute "/usr/bin/vmware-uninstall-tools.pl.
Error: Unable to execute "/usr/bin/vmware-uninstall-tools.pl. 安装vmware tools错误解决办法 很多朋友都在用vmwar ...
- HBuilder生成代码行快捷键
1.在body内输入div.abc按下tab键 效果:<div class="abc"></div> 2.在body内输入div#abc按下tab键 效果: ...
- Ubuntu16.04修改静态ip地址
https://blog.csdn.net/mdw5521/article/details/79270035
- 关于GNU规范的语法扩展
GNU 是一款能用于构建类 Unix 操作系统的计算机软件合集,由自由软件之父 Richard Stallman 开创,于 1983 年 9 月 27 日对外发布.GNU 完全由自由软件(free s ...
- linux系统root用户登录提示“鉴定故障”的解决办法
同事第一次创建虚拟机,遇到此问题,此前我未曾遇到,搜索到的解决办法记录在此,以防之后忘记. 一.重启系统解决(搜索到的该解决办法较多):https://www.cnblogs.com/lippor/p ...
- CSS复合选择器
复合选择器是由两个或多个基础选择器,通过不同的方式组合而成的,目的是为了可以选择更准确更精细的目标元素标签. 交集选择器 交集选择器由两个选择器构成,其中第一个为标签选择器,第二个为class选择器, ...