Add examples and improve description

git-svn-id: https://svn.php.net/repository/phpdoc/en/trunk@290649 c90b9560-bf6c-de11-be94-00142212c4b1
This commit is contained in:
Christopher Jones 2009-11-13 01:05:19 +00:00
parent e50956d252
commit 9a1eec1938

View file

@ -3,7 +3,7 @@
<refentry xmlns="http://docbook.org/ns/docbook" xml:id="function.oci-set-prefetch">
<refnamediv>
<refname>oci_set_prefetch</refname>
<refpurpose>Sets number of rows to be prefetched</refpurpose>
<refpurpose>Sets number of rows to be prefetched by queries</refpurpose>
</refnamediv>
<refsect1 role="description">
@ -14,26 +14,47 @@
<methodparam><type>int</type><parameter>rows</parameter></methodparam>
</methodsynopsis>
<para>
Sets the number of rows to be prefetched after a successful call to
<function>oci_execute</function>. For queries returning a large
number of rows, performance can be improved by increasing the
prefetch count above the
default <link linkend="ini.oci8.default-prefetch">oci8_.default_prefetch</link>
Sets the number of rows to be buffered by the Oracle Client
libraries after a successful query call
to <function>oci_execute</function> and for each subsequent
internal fetch request to the database. For queries returning a
large number of rows, performance can be significantly improved by
increasing the prefetch count above the
default <link linkend="ini.oci8.default-prefetch">oci8.default_prefetch</link>
value.
</para>
<para>
Prefetching is Oracle's efficient way of returning more than one
data row from the database in each network request. This can
result in better network and CPU utilization. The behavior of OCI8
fetching functions is unchanged regardless of the prefetch count.
result in better network and CPU utilization. The buffering of
rows is internal to OCI8 and the behavior of OCI8 fetching
functions is unchanged regardless of the prefetch count. For
example, <function>oci_fetch_row</function> will always return one
row. The prefetch buffer is per-statement and is not used by
re-executed statements or by other connections.
</para>
<para>
Call <function>oci_set_prefetch</function> before
calling <function>oci_execute</function>.
</para>
<para>
A tuning goal is to set the prefetch value to a reasonable size
for the network and database to handle. For queries returning a
very large number of rows, overall system efficiency might be
better if rows are retrieved from the database in several chunks
(i.e set the prefetch value smaller than the number of rows).
This allows the database to handle other users' statements while
your script is processing the current set of rows.
</para>
<para>
Query prefetching was introduced in Oracle 8i. REF CURSOR
prefetching was introduced in Oracle 11gR2 and occurs when PHP is
linked with Oracle 11gR2 libraries and connected to 11gR2 or
linked with Oracle 11gR2 Client libraries and connected to 11gR2 or
previous versions of the database. Nested cursor prefetching was
introduced in Oracle 11gR2 and requires both the Oracle Client
libraries and the database to be version 11gR2.
libraries and the database to be version 11gR2. The prefetch value
is ignored and single-row fetches will be used when prefetching is
not supported.
</para>
</refsect1>
@ -56,7 +77,7 @@
The number of rows to be prefetched.
</para>
<para>
From PHP 5.3.2 and PECL oci8 1.4, <parameter>rows</parameter> may be &gt;= 0. Prior versions required <parameter>rows</parameter> &gt;= 1.
From PHP 5.3.2 and PECL OCI8 1.4, <parameter>rows</parameter> may be &gt;= 0. Prior versions required <parameter>rows</parameter> &gt;= 1.
</para>
</listitem>
</varlistentry>
@ -73,6 +94,14 @@
<refsect1 role="notes">
&reftitle.notes;
<note>
<para>
Prior to PHP 5.3 (Prior to PECL OCI8 1.3.4) the prefetch count was
limited to the lessor of <parameter>rows</parameter> rows and
1024 * <parameter>rows</parameter> bytes. The byte size
restriction has now been removed.
</para>
</note>
<note>
<para>
In PHP versions before 5.0.0 you must use <function>ocisetprefetch</function> instead. &oci.name.compat.note;
@ -80,12 +109,136 @@
</note>
</refsect1>
<refsect1 role="examples">
&reftitle.examples;
<para>
<example>
<title>Changing the default prefetch value for a query</title>
<programlisting role="php">
<![CDATA[
<?php
$conn = oci_connect("hr", "welcome", "localhost/XE");
$stid = oci_parse($conn, "SELECT * FROM myverybigtable");
oci_set_prefetch($stid, 300); // Set before calling oci_execute()
oci_execute($stid);
echo "<table border='1'>\n";
while ($row = oci_fetch_array($stid, OCI_ASSOC+OCI_RETURN_NULLS)) {
echo "<tr>\n";
foreach ($row as $item) {
echo " <td>".($item !== null ? htmlentities($item, ENT_QUOTES) : "&nbsp;")."</td>\n";
}
echo "</tr>\n";
}
echo "</table>\n";
oci_free_statement($stid);
oci_close($conn);
?>
]]>
</programlisting>
</example>
</para>
<para>
<example>
<title>Changing the default prefetch for a REF CURSOR fetch</title>
<programlisting role="php">
<![CDATA[
<?php
/*
Create the PL/SQL stored procedure as:
CREATE OR REPLACE PROCEDURE myproc(p1 OUT SYS_REFCURSOR) AS
BEGIN
OPEN p1 FOR SELECT * FROM all_objects WHERE ROWNUM < 5000;
END;
*/
$conn = oci_connect("hr", "welcome", "localhost/XE");
$stid = oci_parse($conn, "BEGIN myproc(:rc); END;");
$refcur = oci_new_cursor($conn);
oci_bind_by_name($stid, ':rc', $refcur, -1, OCI_B_CURSOR);
oci_execute($stid);
// Change the prefetch before executing the cursor.
// REF CURSOR prefetching works when PHP is linked with Oracle 11gR2 Client libraries
oci_set_prefetch($refcur, 200);
oci_execute($refcur);
echo "<table border='1'>\n";
while ($row = oci_fetch_array($refcur, OCI_ASSOC+OCI_RETURN_NULLS)) {
echo "<tr>\n";
foreach ($row as $item) {
echo " <td>".($item !== null ? htmlentities($item, ENT_QUOTES) : "&nbsp;")."</td>\n";
}
echo "</tr>\n";
}
echo "</table>\n";
oci_free_statement($refcur);
oci_free_statement($stid);
oci_close($conn);
?>
]]>
</programlisting>
</example>
</para>
<para>
If PHP OCI8 fetches from a REF CURSOR and then passes the REF
CURSOR back to a second PL/SQL procedure for further processing,
then set the REF CURSOR prefetch count to <constant>0</constant> to
avoid rows being "lost" from the result set. The prefetch value is
the number of extra rows fetched in each OCI8 internal request to
the database, so setting it to <constant>0</constant> means only
fetch one row at a time.
<example>
<title>Setting the prefetch value when passing a REF CURSOR back to Oracle</title>
<programlisting role="php">
<![CDATA[
<?php
$conn = oci_connect("hr", "welcome", "localhost/orcl");
// get the REF CURSOR
$stid = oci_parse($conn, "BEGIN myproc(:rc_out); END;");
$refcur = oci_new_cursor($conn);
oci_bind_by_name($stid, ':rc_out', $refcur, -1, OCI_B_CURSOR);
oci_execute($stid);
// Display two rows, but don't prefetch any extra rows otherwise
// those extra rows would not be passed back to myproc_use_rc().
// A prefetch value of 0 is allowed in PHP 5.3.2 and PECL OCI8 1.4
oci_set_prefetch($refcur, 0);
oci_execute($refcur);
$row = oci_fetch_array($refcur);
var_dump($row);
$row = oci_fetch_array($refcur);
var_dump($row);
// pass the REF CURSOR to myproc_use_rc() to do more data processing
// with the result set
$stid = oci_parse($conn, "begin myproc_use_rc(:rc_in); end;");
oci_bind_by_name($stid, ':rc_in', $refcur, -1, OCI_B_CURSOR);
oci_execute($stid);
?>
]]>
</programlisting>
</example>
</para>
</refsect1>
<refsect1 role="seealso">
&reftitle.seealso;
<para>
<simplelist>
<member>
<link linkend="ini.oci8.default-prefetch">oci8_.default_prefetch</link>
<link linkend="ini.oci8.default-prefetch">oci8.default_prefetch</link>
ini option
</member>
</simplelist>