Converting REF CURSOR to PIPE for Performance in PHP OCI8 and PDO_OCI
原文地址:https://blogs.oracle.com/opal/entry/converting_ref_cursor_to_pipe
REF CURSORs are common in Oracle's stored procedural language PL/SQL. They let you pass around a pointer to a set of query results.
However in PHP, PDO_OCI doesn't yet allow fetching from them. And fetching from REF CURSORS in OCI8 is not as fast as doing a normal query. This is because of two architectural decisions: OCI8 doesn't use the preferred Oracle style of "array fetching". Instead it uses "prefetching", but prefetching from REF CURSORS isn't supported by Oracle for various reasons (including that array fetching is available and recommended....)
One workaround, when you can't rewrite the PL/SQL code to do a normal query, is to write a wrapper function that pipes the output.
For this example, the "fixed" procedure that you can't change is:
create or replace procedure myproc(p1 out sys_refcursor) as
begin
open p1 for select last_name from employees;
end;
The wrapper function follows the performance tip in 12-14 of Tuning PL/SQL Applications for Performance and uses a BULK COLLECT:
create or replace package myplmap as
type outtype is record ( -- structure of the ref cursor in myproc
last_name varchar2()
);
type outtype_set is table of outtype;
function maprctopl return outtype_set pipelined;
end;
/
show errors create or replace package body myplmap as
function maprctopl return outtype_set pipelined is
outrow outtype_set;
p_rc sys_refcursor;
rlim pls_integer := ; -- fetch batches of rows at a time
begin
myproc(p_rc); -- call the original procedure
loop
fetch p_rc bulk collect into outrow limit rlim;
exit when outrow.count = ;
for i in .. outrow.count loop
pipe row (outrow(i));
end loop;
end loop;
end maprctopl;
end myplmap;
The PHP OCI8 code to query the pipelined function is:
<?php $c = oci_connect('hr', 'hrpwd', '//localhost/XE'); $s = oci_parse($c, "select * from table(myplmap.maprctopl())");
oci_execute($s);
oci_fetch_all($s, $res);
var_dump($res); ?>
You could use this query in PDO_OCI too.
I found it doubled the performance of smallish tests with a local database (from small time to even smaller time). The change is more dramatic from a distant, remote database. With a query returning a large number of rows it dropped the runtime to 35 seconds from about 24 minutes.
This tip will appear in the next edition of the Underground PHP and Oracle Manual.
Update: Prefetching from REF CURSORS is supported in Oracle 11gR2. See Oracle Database 11gR2 Enhancements for PHP
Converting REF CURSOR to PIPE for Performance in PHP OCI8 and PDO_OCI的更多相关文章
- Report_报表中Ref Cursor数据源的概念和用法(案例)
2014-06-22 Created By BaoXinjian
- REF CURSOR和CURSOR
REF CURSOR DECLARE TYPE TY_EMP_CUR IS REF CURSOR; V_Emp_Cur TY_EMP_CUR; V_Id EMP.ID%TYPE; BEGIN OPEN ...
- Entity Framework 5.0.0 Function Import 以及 ODP. NET Implicit REF CURSOR Binding使用简介
源代码 概要: 1,说明如何使用Entity Framework中的function import功能. 2,说明如何使用ODP.NET的隐式REF CURSOR绑定(implicit REF CUR ...
- Oracle ref cursor和sys_refcursor
1. 自定义 ref cursor 和 sys_refcursor; 2. sys_refcursor 做为参数传递结果集; 3. ref cursor 做为参数传递结果集; 1. 自定义 ref c ...
- oracle中REF Cursor用法
from:http://www.111cn.net/database/Oracle/42873.htm 1,什么是 REF游标 ? 动态关联结果集的临时对象.即在运行的时候动态决定执行查询. 2,RE ...
- PLSQL中显示Cursor、隐示Cursor、动态Ref Cursor差别
一.显式cursor 显式是相对与隐式cursor而言的,就是有一个明白的声明的cursor.显式游标的声明类似例如以下(具体的语法參加plsql ref doc ): cursor cursor_n ...
- ORACLE中RECORD、VARRAY、TABLE、IS REF CURSOR 的使用及实例详解
ORACLE中RECORD.VARRAY.TAB.IS REF CURSOR LE的使用及实例详解 create or replaceprocedure PRO_RECORD_ROW_TAB_EXAM ...
- oracle sys_refcursor用法和ref cursor区别
--创建过程,参数为sys_refcursor,为out型 create or replace procedure aabbsys_refcursor(o out sys_refcursor) is ...
- oracle 存储过程及REF CURSOR的使用
基本使用方法及示例 1.基本结构: CREATE OR REPLACE PROCEDURE 存储过程名字 (参数1 IN NUMBER,参数2 IN NUMBER) AS 变量1 INTEGER := ...
随机推荐
- ASP.NET压力测试
本文导读:对于直接面对互联网用户的WEB应用,在开发设计的时候必须格外小心,因为谁也不知道在单位时间内WEB程序访问和运行的速度.所以,在程序设计完成以后,最后针对程序进行一些严格的甚至是苛刻的测试, ...
- centos:添加用户
初步进入centos学习,配置用户 1,创建用户 创建用户 hadoop [root@master spark]# useradd hadoop [root@master spark]# 2,创建密码 ...
- Flask的集中控制
想通过一个统一的机制,同时允许一些公共的逻辑 {% if args["NoUser"] %} 无用户! {% else %} <!DOCTYPE html PUBLIC &q ...
- java 让图片变黑白
import java.awt.Image;import java.awt.color.ColorSpace;import java.awt.image.BufferedImage;import ja ...
- [R]Kick start
- Android LazyList 从网络获取图片并缓存
原演示地址 本文内容 环境 演示 LazyList 从网络获取图片并缓存 参考资料 本文是 Github 上的一个演示,通过网络获取歌手专辑的缩略图,并显示在 ListView 控件中.该演示具备将缩 ...
- PAT《数据结构学习与实验指导》实验项目集 2-05 2-06 2-07 2-08
题目地址:here pat 2-05 求集合数据的均方差 没什么可说的,大水题 #include<cstdio> #include<cmath> int main() { in ...
- 【树莓派】crontab设置Linux设备定时重启
简介:设置Linux设备定时重启或者关机 问题:有台设备每天总需要使用的人手动重启一下才可以正常工作,但是检查了日志,看起来服务一切都正常.时间和正确时间相差4mins. 解决办法: 1.增加定时任务 ...
- Ant详解之-path、classpath和fileset
转自:http://www.cnblogs.com/itech/archive/2011/11/01/2231206.html 一 .<path/> 和 <classpath/> ...
- 在Windows中监视IO性能
附:在Windows中监视IO性能 本来准备写一篇windows中监视IO性能的,后来发现好像可写的内容不多,windows在细节这方面做的不是那么的好,不过那些基本信息还是有的. 在Windows中 ...