関数・クラス解説
oci_set_prefetch
version:PHP 5, PHP 7, PECL OCI8 >= 1.1.0 (公式)クエリがプリフェッチする行数を設定する
公式リファレンス
書式
oci_set_prefetch ( resource $statement , int $rows ) : bool
説明
oci_execute() のコール、およびそれに伴う内部的なデータベースへのリクエストがすべて成功した後に Oracle Client ライブラリがバッファに取り込む行数を設定します。 クエリが返す結果の行数が多くなる場合は、プリフェッチ行数をデフォルトの oci8.default_prefetch より大きくしておくとパフォーマンスが劇的に向上します。
プリフェッチは、Oracle がデータベースからデータを取得する際の効率的な方法で、 一回のネットワークリクエストで複数の行を取得します。こうすれば、 ネットワークや CPU の利用効率がよくなります。 行のバッファリングは OCI8 の内部的なものであり、 プリフェッチ行数が変わっても OCI8 のフェッチ関数群の挙動は変わりません。 たとえば、oci_fetch_row() は、常に一行だけを返します。 プリフェッチバッファはステートメント単位で設定されるものであり、 ステートメントを再実行したときや他の接続から実行したときには使われません。
oci_set_prefetch() は oci_execute() の前にコールします。
ネットワークやデータベースの状況を考慮して、 プリフェッチの値を適切な大きさに設定することがチューニングの目標です。 大量の行を返すクエリの場合は、データベースからの行の取得を いくつかの塊に分けて行うとシステム全体の効率が良くなるかもしれません (つまり、プリフェッチの値を行数より小さめに設定するということです)。 こうすれば、PHP スクリプトが現在の行を処理している間にも データベースが別のユーザーからのステートメントを処理できるようになります。
クエリのプリフェッチが導入されたのは、Oracle 8i からです。 REF CURSOR のプリフェッチが導入されたのは Oracle 11gR2 からで、 PHP を Oracle 11gR2 以降のクライアントライブラリとリンクすれば使えます。 ネストしたカーソルのプリフェッチが導入されたのは Oracle 11gR2 からで、 これを使うには Oracle クライアントライブラリと接続先のデータベースがどちらも 11gR2 以降でなければなりません。
プリフェッチは、LONG あるいは LOB 列を含むクエリには対応していません。 プリフェッチに対応していないクエリの場合はプリフェッチの値は無視され、 どんな場合でも一行単位でフェッチします。
Oracle Database 12c では、PHP で設定したプリフェッチの値を Oracle のクライアント設定ファイル oraaccess.xml で上書きできます。 詳細は、Oracle のドキュメントを参照ください。
パラメータ
- statement
- oci_parse() で作成してoci_execute() で実行した有効な OCI8 ステートメント ID、あるいは REFCURSOR ステートメント ID。
- rows
- プリフェッチする行数。>= 0
返値
成功した場合に TRUE を、失敗した場合に FALSE を返します。
更新履歴
バージョン | 説明 |
---|---|
PECL OCI8 1.4 | これより前のバージョンでは、rows は 1 以上でなければなりませんでした。 |
PECL OCI8 1.3.4 | これより前のバージョンでは、プリフェッチの上限は rows 行と 1024 * rows バイトのうちの少ないほうでした。 バイト数の制限は、このバージョンで取り除かれました。 |
サンプル
例1 クエリのデフォルトプリフェッチ値の変更
$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 "\n";
while ($row = oci_fetch_array($stid, OCI_ASSOC+OCI_RETURN_NULLS)) {
echo "\n";
foreach ($row as $item) {
echo " ".($item !== null ? htmlentities($item, ENT_QUOTES) : " ")." \n";
}
echo " \n";
}
echo "
\n";
oci_free_statement($stid);
oci_close($conn);
例2 REF CURSOR のデフォルトプリフェッチの変更
/*
下記のようにして 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 11R2 以降のクライアントライブラリとリンクしたときです。
oci_set_prefetch($refcur, 200);
oci_execute($refcur);
echo "\n";
while ($row = oci_fetch_array($refcur, OCI_ASSOC+OCI_RETURN_NULLS)) {
echo "\n";
foreach ($row as $item) {
echo " ".($item !== null ? htmlentities($item, ENT_QUOTES) : " ")." \n";
}
echo " \n";
}
echo "
\n";
oci_free_statement($refcur);
oci_free_statement($stid);
oci_close($conn);
PHP OCI8 で REF CURSOR からフェッチした内容を別の PL/SQL プロシージャに渡すときには、REF CURSOR のプリフェッチ行数を 0 に設定して行が結果セットから "失われる" ことを防ぎます。 プリフェッチの値は OCI8 内部でのデータベースへのリクエスト時に余計に取得する行数です。 つまり、0 に設定すると一度に一行だけ取得するということになります。
例3 REF CURSOR を Oracle に戻すときのプリフェッチの設定
$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() には戻されません。
// プリフェッチに 0 を設定できるようになったのは 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);
参考
ワード検索
※入力キーワードが、関数名・説明文・タグに含まれるものを検索関数名アルファベット別
最終更新一覧
●stristr
大文字小文字を区別せず文字列を検索し、ヒット箇所以降(あるいは以前)の文字列を返却
●stripslashes
バックスラッシュでエスケープされた文字列から、バックスラッシュを取り除く
●stripos
大文字小文字を区別せずに文字列が最初に現れる位置を取得する
●stripcslashes
addcslashes() でクォートされた文字列をアンクォートする
●strip_tags
文字列から HTML と PHP のタグを除去して返却
●strcspn
指定した文字が最初に現れる位置を調べる
●strcoll
ロケールに基づいて2つの文字列を比較し同じか(あるいは大小)を判定する
●strcmp
2つの文字列を比較し同じか(あるいは大小)を判定する
●strchr
strstr() のエイリアス
●strcasecmp
2つの文字列を比較(大文字小文字を区別せず同じとみなす)
カテゴリー一覧
PHP の振る舞いの変更
音声フォーマットの操作
認証サービス
コマンドライン関連
圧縮およびアーカイブ
暗号
データベース関連
日付および時刻関連
ファイルシステム
自然言語および文字エンコーディング
画像処理および作成
メール関連
数学
テキスト以外の MIME 型
プロセス制御
その他の基本モジュール
その他のサービス
検索エンジン用の拡張モジュール
サーバー固有のモジュール
セッション関連
テキスト処理
変数・データ型関連
ウェブサービス
Windows 用のモジュール
XML 操作
GUI用の拡張モジュール