phpを使用してOracle Database XEとMySQLへのコネクションプーリングの方法・性能を比較しました。MySQL編

まず始めに

文章が長くなってしまったので、MySQL編とOracle Database XE編に分けて記事にしたいと思います。

[追記]
コメント欄にてご指摘頂いた件がありますので、下記検証結果は今のところ正しいと言えないかもしれません。
僕がこのように検証しましたという程度で読んで頂けると幸いです。
再度違う方法で検証&報告します。


最近”コネクションプーリング”というのを知りました。

コネクションプーリングとは

データベースにアクセスする時、アクセスのたびに接続(コネクション)を確立するのではなく、あらかじめ一定数のコネクションを確立しておき、それを使い回す手法。データベースアクセスの負荷を減らすために用いられる。



引用元:コネクションプーリング 【connection pooling】 | ソフトウェア用語辞典
http://ew.hitachi-system.co.jp/w/E382B3E3838DE382AFE382B7E383A7E383B3E38397E383BCE383AAE383B3E382B0.html

色々php,mysql関連の本読みましたけど、コネクションプーリングについて触れている本ってあったかな?
コネクションプーリングをウェブで調べてみると賛否両論あるみたいですけども、実際のとこ動作させてみないとわからないもんで。

そこで、phpを使用して、Oracle Database XEとMySQLへのコネクションプーリングの方法・性能を比較しました。

処理性能を比較する方法

まず処理性能を比較する為のスクリプトは、下記の実行時間を表示する標準関数を使用します。

time.php
<?php
  $start = microtime();

  for($i=0;$i<10000;$i++){}

  $end = microtime();
  echo "\n".$end - $start;
?>

実行すると

php time.php
0.000884

こんな感じで実行時間が表示されます。
この実行時間で処理性能を比較したいと思います。

参考サイト
http://nakayalog.net/?p=235


まずphp + MySQLを使用してコネクションプーリングを利用する方法を調べました。

mysql_pconnect関数
http://jp2.php.net/manual/ja/function.mysql-pconnect.php

持続的データベース接続についての詳しい説明
http://jp2.php.net/manual/ja/features.persistent-connections.php

mysql_pconnect関数を使用すると、スクリプトの実行が終了してもMySQLとの接続が閉じられないということらしいです。
じゃあ、いつMySQLとの接続が切れるんだって話だけども…。

まあまあ早速実験開始です。


mysql_connect関数でINSERTクエリ1万回の速度実験

mysql_connectデータベースの作成

CREATE DATABASE `mysql_connect` ;

test_tableテーブルの作成

CREATE TABLE `mysql_connect`.`test_table` (
`test_field` INT NOT NULL ,
PRIMARY KEY ( `test_field` )
) ENGINE = InnoDB

mysql_connect.phpの作成

<?php
$link = mysql_connect('localhost', 'root', '[パスワード]');
mysql_select_db('mysql_connect', $link);

$result = mysql_query("INSERT INTO `mysql_connect`.`test_table` (
                       `test_field`
                       ) VALUES (
                       ".$argv[1]."
                       );");
mysql_close($link);
?>

mysql_connect.php用のtime.phpの作成

<?php
  $start = microtime();

  for($i=0;$i<10000;$i++){
    exec("php mysql_connect.php $i");
  }

  $end = microtime();
  echo "\n".$end - $start;
?>


それでは実行です。

php time.php
-0.16822

っておい!マイナスってなんだよ!過去行っちゃいましたよ。

なんでだろーと思って、time.phpを下記に修正してデバッグ

<?php
  $start = microtime();

  for($i=0;$i<10000;$i++){
    exec("php mysql_connect.php $i");
    echo microtime()."\n";//ここを追加しました。
  }

  $end = microtime();
  echo "\n".$end - $start;
?>

実行結果

0.13497400 1235517635
0.21877200 1235517635
0.30137900 1235517635
0.38148700 1235517635
0.46109300 1235517635
0.51826300 1235517635
0.57506100 1235517635
0.64548400 1235517635
0.72877100 1235517635
0.80903100 1235517635
0.89188100 1235517635
0.97485400 1235517635
0.12529500 1235517636
0.20909600 1235517636
0.29497800 1235517636
0.37752300 1235517636
0.46024800 1235517636
0.54040300 1235517636
0.60471400 1235517636
0.66184100 1235517636
0.71674400 1235517636
0.77201900 1235517636
0.82703400 1235517636
…

なるほど、[コンマ 秒]って事ですね。

では、それ用にtime.phpを下記の様に修正

mysql_connect.php用のtime.phpの作成(修正版)

<?php
  $start = array_sum(explode(" ",microtime()));

  for($i=0;$i<10000;$i++){
    exec("php mysql_connect.php $i");
  }

  $end = array_sum(explode(" ",microtime()));
  echo "\n".$end - $start;
?>


それでは再度実行です。

php time.php
785.43530797958

かなり時間かかりましたね。
InnoDBというのも遅い原因かもしれません。


mysql_pconnect関数でINSERTクエリ1万回の速度実験

データベースとテーブルは先程のを使用します。

mysql_pconnect.phpの作成

<?php
$link = mysql_pconnect('localhost', 'root', '[パスワード]');
mysql_select_db('mysql_connect', $link);

$result = mysql_query("INSERT INTO `mysql_connect`.`test_table` (
                       `test_field`
                       ) VALUES (
                       ".$argv[1]."
                       );");
?>

mysql_close()を使用した行を削除しただけですが、きちんとコネクションプーリング出きるでしょうか?

mysql_pconnect.php用のtime.phpの作成

<?php
  $start = array_sum(explode(" ",microtime()));

  for($i=0;$i<10000;$i++){
    exec("php mysql_pconnect.php $i");
  }

  $end = array_sum(explode(" ",microtime()));
  echo "\n".$end - $start;
?>

それでは実行です。

php time.php
775.68468093872

10秒短くなったけど…少し違う感じがするなあ。


MySQLコネクションプーリングの結果

一応速度の向上を測る事が出来ましたが、微々たる速度向上という結果でした。


php + MySQLでの結果は良い結果は出ませんでしたが、改善方法をお知りの方は教えて下さい!

次のエントリーではphp + Oracle Database XEのコネクションプーリングを検証したいと思います!

[追記]
id:sh2さんからご指摘頂きました!
同じような検証をされたようです。
http://d.hatena.ne.jp/sh2/20081104/



[PR]Spreeの情報を集めています。

ECを持ちたい方、仕事でECを使いたい方向けのコミュニティサイトです。
このサイトでは世界で最も使用されているECの1つであるSpreeについての情報を提供しています。
http://spreecommerce.jp/