|
ここにある情報はかなり古くなっており、正しくなくなっている可能性があります。掲載しているサンプルコードiなどは、最新のPHPでは動作しない、もしくは、別途設定・調整が必要になるかも知れません。情報を鵜呑みにせず、あなたの手を動かして、あなたの目で確認してください。
Oracleのあるテーブルに存在する全データを取得する場合、OCIFetchでループした場合とOCIFetchIntoではどちらが早いのか、ふと思ってしまったのでやってみました。予想はついていたのですが、実際どのくらい違うのか実験しました。
今回の環境ですが、さっくり以下のような感じです。
- Webサーバ:P3-733MHz / Apache 1.3.20 + PHP4.1.0 + Oracle 8.1.6i Client
- DBサーバ:Celeron500MHz / Oracle 8.1.6i
実験に使ったスクリプトは以下のようなもので、ROWIDのみをSELECTし、OCIExecute後のFetch部分のみmicrotime関数で測定しています。
●実験用スクリプト1(OCIFetch)
<?php
$dbc = OCILogon("xxxx", "yyyy", "zzzz");
$sql = "SELECT ROWIDTOCHAR(rowid) X FROM aaaa ";
echo "\$sql=$sql<br/>";
$parse = OCIParse($dbc, $sql);
OCIExecute($parse);
$st = getMicrotime();
while (OCIFetch($parse)) {
$a[$cnt++] = OCIResult($parse, "X");
}
$et = getMicrotime();
OCIFreeStatement($parse);
OCILogOff($dbc);
echo "d=" . ($et - $st);
?>
<?php
function getmicrotime()
{
list($usec, $sec) = explode(" ",microtime());
return ((float)$sec + (float)$usec);
}
?>
●実験用スクリプト2(OCIFetchInto。差分だけ)
<?php
:
$sql = "SELECT ROWIDTOCHAR(rowid) X FROM aaaa ";
:
$st = getMicrotime();
$nrows = OCIFetchStatement($parse, &$arr);
$et = getMicrotime();
:
?>
結果ですが、以下のようになりました。ほんの僅かですが、OCIFetchIntoの方が早かったです(18000件で1秒程度)。また、Fetch件数と所要時間はほぼリニアな関係でした。
実験をやってる最中にSELECTするカラムを変えると結果がかなり違うことに気付きました。そこで、よくやってしまいそうな「SELECT *」の場合についてもOCIFetchIntoのみですが測定しました。使用したスクリプトと結果は以下の通りとなりました。
●実験用スクリプト3(2との差分)
<?php
ini_set("max_execution_time", 90);
:
$sql = "SELECT * FROM aaaa ";
:
?>
こちらははっきりと差がでました。実際にはカラム数やレコード全体のサイズに依存していることになると思います。まあ、考えてみると、不要なカラムをSELECTするということは、DBからのデータ転送量が増える&連想配列に格納するなどの処理量が増える、ということになるハズですので、最終的には「パフォーマンスの低下を招く」ということになるでしょう。
今日の教訓:「SELECTするカラムは必要最低限にしましょう」
|