(PHP 5, PHP 7, PECL OCI8 >= 1.1.0)
oci_set_prefetch — Устанавливает количество строк, которые будут автоматически выбраны в буфер
$statement
, int $rows
)Устанавливает количество рядов, которые будут выбраны в буфер клиентскими библиотеками Oracle сразу после удачного вызова oci_execute() и для каждого последующего внутреннего запроса данных к базе. Производительность может быть значительно увеличена для запросов, возвращающих большое количество рядов, с помощью установки значения предварительной выборки больше значения по умолчанию oci8.default_prefetch.
Предварительная выборка - это эффективный механизм Oracle, позволяющий возвращать больше одного ряда результата из базы данных за каждый сетевой запрос. Это дает более рациональное использование сети и процессора. Буферизация рядов происходит внутри OCI8, поэтому поведение функций выборки OCI8 никак не зависит от размера предварительной выборки. Например, oci_fetch_row() всегда возвращает один ряд. Буфер предварительной выборки резервируется отдельно на каждый запрос и не используется второй раз в повторно запущенных запросах или в других соединениях.
Перед вызовом oci_execute() вызовите oci_set_prefetch().
Смысл настройки размера предварительной выборки состоит в подборе удобного значения для передачи в сети и обработки в базе данных. Для запросов, возвращающих очень большое количество рядов, общая производительность системы может быть лучше, если ряды будут возвращаться в несколько приемов (т.е. установить размер предварительной выборки меньше количества рядов). Это позволит базе данных обрабатывать запросы других пользователей в течение обработки PHP-скриптом текущего результата запроса.
Предварительная выборка запросов появилась в Oracle 8i. Предварительная выборка REF CURSOR появилась в Oracle 11gR2 и может быть применена в случае, если PHP слинкован с клиентскими библиотеками Oracle 11gR2 и старше. Предварительная выборка вложенных курсоров была добавлена в Oracle 11gR2 и требует наличия версии 11gR2 и старше как для клиентских библиотек Oracle, так и для используемой базы данных.
Предварительная выборка не поддерживается, если запросы содержат LONG или LOB столбцы. Значение предварительной выборки игнорируется и во всех ситуациях, не поддерживающих предварительную выборку, будет использована построчная выборка.
При использовании Oracle Database 12c, предварительная выборка заданная PHP может быть изменена конфигурационным файлом oraaccess.xml клиента Oracle. Обратитесь к документации Oracle за дополнительной информацией.
statement
Корректный идентификатор выражения OCI8, полученный из oci_parse() и исполненный функцией oci_execute(), или идентификатор выражения REF CURSOR.
rows
Количество рядов предварительной выборки, >= 0
Возвращает TRUE
в случае успешного завершения или FALSE
в случае возникновения ошибки.
Версия | Описание |
---|---|
5.3.2 (PECL OCI8 1.4) |
До этой версии rows должен был быть >= 1.
|
5.3.0 (PECL OCI8 1.3.4) |
До этой версии предварительная выборка была ограничена к меньшему
из значений rows рядов и 1024
* rows байт. Теперь ограничение по размеру
байт снято.
|
Пример #1 Смена значения предварительной выборки по умолчанию для запроса
<?php
$conn = oci_connect('hr', 'welcome', 'localhost/XE');
$stid = oci_parse($conn, 'SELECT * FROM myverybigtable');
oci_set_prefetch($stid, 300); // Устанавливаем перед вызовом 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) : "")."</td>\n";
}
echo "</tr>\n";
}
echo "</table>\n";
oci_free_statement($stid);
oci_close($conn);
?>
Пример #2 Смена значения предварительной выборки по умолчанию для выборки REF CURSOR
<?php
/*
Создайте хранимую процедуру PL/SQL следующим образом:
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);
// Меняем размер предварительной выборки перед запуском курсора.
// Предварительная выборка REF CURSOR работает в случае линковки PHP
// с клиентскими библиотеками Oracle 11gR2 и старше
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) : "")."</td>\n";
}
echo "</tr>\n";
}
echo "</table>\n";
oci_free_statement($refcur);
oci_free_statement($stid);
oci_close($conn);
?>
Если PHP OCI8 производит выборку из REF CURSOR, а затем передает
REF CURSOR обратно в другую PL/SQL-процедуру для дальнейшей обработки,
необходимо установить размер предварительной выборки REF CURSOR в
0
, чтобы избежать "потери" рядов из результата.
Значение предварительной выборки - это количество "лишних" рядов, полученных
каждым внутренним запросом OCI8 к базе данных, поэтому установка его
в 0
означает выборку только одного ряда за один раз.
Пример #3 Установка значения предварительной выборки при передаче REF CURSOR обратно в Oracle
<?php
$conn = oci_connect('hr', 'welcome', 'localhost/orcl');
// получение 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);
// Отображаем два ряда, но больше не предвыбираем других рядов, иначе
// эти ряды не будут переданы обратно в myproc_use_rc().
// Нулевое значение предварительной выборки было разрешено в версии PHP 5.3.2 и 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);
// передаем REF CURSOR в myproc_use_rc() для дальнейшей обработки результата
$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);
?>