PHPのDB関数 vs システム経由SQL
AjaSQLは、サーバー側のゲートウエイにPHPを利用しました。PHPは十分に普及しており、
PHPを使いこなせる利用者が多いからです。
でも、
AjaSQLは、PHPに用意されている、充実した魅力的なDB関数群を使いませんでした。
AjaSQLは、JavaScriptから受け取ったSQL文を、直接システム上のSQLiteやMySQLへ渡してしまいます。
理由は、簡単です。その方が早かったからです。
試しに、該当するPHPの部分だけで応答速度を比較してみます。
12万件の郵便番号DBに対して、
SQL:select * from zip where code = '3001288' ; 結果数1件 を実行します。
|
PHPのDB関数→Sample |
直接シェルでSQLite→Sample |
| 1回目 |
0.0963709354401 秒 |
0.0843710899353 秒 |
-12% |
| 2回目 |
0.0950171947479 秒 |
0.0846970081329 秒 |
-11% |
| 3回目 |
0.094624042511 秒 |
0.0839648246765 秒 |
-11% |
念のため、同じく12万件の郵便番号DBに対して、
SQL:select * from zip where code like '3%' ; 結果数約一万件 を実行してみます。
|
PHPのDB関数→Sample |
直接シェルでSQLite→Sample |
| 1回目 |
0.153703927994 秒 |
0.0992729663849 秒 |
-35% |
| 2回目 |
0.159020900726 秒 |
0.100910902023 秒 |
-37% |
| 3回目 |
0.154000997543 秒 |
0.099928855896 秒 |
-35% |
PHPのDB関数に対して、シェルへ渡す方式は、応答速度が、Min 11% ~ Max 37% 改善されています。
逆に言うと、code like '3%'では、PHPのDB関数は60%近く遅いということになります。
この結果、AjaSQLは、PHPを利用しながら、通常のPHPのDB処理以上のパフォーマンスを出しています。
とはいえ、システム経由でSQLを実行すればPHPも同様に早くなるわけですが、AjaSQLが、結果セット受信後は、
クライアント側へ処理が移ってしまうのに対して、一般的なPHPでは、結果セット受信後もサーバーでの処理が続き、
クライアントを待たせる形になるところが違います。
前者のベンチマークに使ったソースは、下記の通りです。
PHPのDB関数→Sample
<?php
function microtime_float()
{
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
$stime = microtime_float();
//データベースオープン
$db = sqlite_open('/var/www/ajasql.org/html/sample/ajasql/zipdb');
//SQLクエリの実行
$result = sqlite_query($db, "select * from zip where code = '3001288' ;");
$res="";
while ($row = sqlite_fetch_array($result,SQLITE_ASSOC))
{
$res .= $row['code'].",".$row['address'];
}
//出力
print "$res";
$etime = microtime_float();
$sa = $etime-$stime;
print "<hr>結果数1件 終了$etime - 開始$stime = <font color=red>$sa 秒</font>";
print "<br>SQL:select * from zip where code = '3001288' ;";
?>
直接シェルでSQLite→Sample
<?php
function microtime_float()
{
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
$stime = microtime_float();
//出力
print `sqlite -list -separator "," /var/www/ajasql.org/html/sample/ajasql/zipdb "select * from zip where code = '3001288' ;" `;
$etime = microtime_float();
$sa = $etime-$stime;
print "<hr>結果数1件 終了$etime - 開始$stime = <font color=red>$sa 秒</font>";
print "<br>SQL:select * from zip where code = '3001288' ;";
?>
注意:当然ながら、このようなベンチマークは、これしかないという方法ではありませんし、実際の作り方とも異なりますから、
使い方や環境等によって一律の結果が出るわけではありません。保証などはできませんのであらかじめご了承ください。
#ちなみに、このテストをやってみて、気づいたことがあります。PHPの関数でデータベースオープンしてから、
そのまま何度クエリを繰り返しても、オープンごと繰り返しても全然速度が変わりません。というか、遅くなったりもします。
つまり、接続という点でのメリットがないぽいのです。ちなみに、AjaSQLは、接続きっぱり使い捨て未練なし(^^;です。