ZAPAnet総合情報局 > ZAPAブログ2.0 > PDO、PEAR::DB、MySQL関数の速度比較

PDO、PEAR::DB、MySQL関数の速度比較

2007年04月07日 プログラミングTIPS
PHPからデータベースを扱うことは良くあります。
その際、一体どういった方法でデータベースを扱うのが一番優れているのか、けっこう悩むところでもあります。
PHP4の頃までは、抽象化してデータベースを扱うために、PEAR::DBやPEAR::MDBなどが多く使われていました。
PHP5になってから、最近では速度面で有利とされるPDOが流行っています。

簡単な処理速度比較などを載せているサイトもありますが、「PHP用アクセラレータ」導入済みでの比較結果はあまり載っていません。
自分で扱っているサーバーと似たような構成での処理速度比較でないと、速度比較の信頼性も落ちます。

そこで、今回はPHP5.2.1とeAcceleratorをインストールしているサーバーで実際にPDO、PEAR::DB、ネイティブのMySQL関数の速度比較を行ってみました。

実験環境

実験をしたサーバーの環境は、下表の通りです。
環境 バージョン
OS CentOS4
PHP 5.2.1
PHPアクセラレータ eAccelerator0.9.5
MySQL 4.1
PEAR::DB 1.7.11

また、データベースの処理速度比較をする上で、今回は実運用面で比較対象としやすい、当ブログ「[Z]ZAPAブロ~グ2.0」のエントリデータを対象としました。
たまに、「10件しか存在しないDBから10件取得する」比較を行っているサイトもあったりしますが、件数が少なすぎても、あまり信頼性が高くありません。
2004年7月から投稿し続け、エントリが1000件弱存在する当ブログのDBを対象としました。


実験方法

実験方法は、以下のようにしました。
1.MySQLデータベースに接続する
2.[Z]ZAPAブロ~グ2.0の全1000件弱のエントリデータから全件取得する
3.全エントリ本文を変数に代入する
4.データベースから切断する
この処理にかかる時間を、PDO 関数、PEAR::DBとネイティブ関数であるMySQL関数MySQLi関数でそれぞれ計測してみました。
一つのスクリプト内で、それぞれの方法でMySQLサーバーに接続して、それぞれSQL文を発行し、MySQLサーバーから切断しました。
また、キャッシュの効果を測定するために、同スクリプト内で同じSQL文を2回発行し、計8回DB接続、クエリ発行、DB切断を行いました。
(mysqli→pdo→pear::DB→mysql→mysqli(2)→pdo(2)→pear::DB(2)→mysql(2)の順番です)


実験結果

実験結果は、下表の通りです。
(キャッシュの効果を測定するために、同スクリプト内で同じSQL文を2回発行し、(2)としています)
ブログ全データ(約千件)をSELECTしたときにかかった秒数
処理方法 1回目 2回目 3回目 4回目 5回目
mysqli: 0.00892秒 0.00902秒 0.00885秒 0.00875秒 0.00905秒
pdo: 0.01536秒 0.01416秒 0.01570秒 0.01369秒 0.01370秒
pear::DB: 0.02275秒 0.02669秒 0.02460秒 0.02257秒 0.02260秒
mysql: 0.01065秒 0.01118秒 0.01066秒 0.05339秒 0.01064秒
mysqli(2): 0.00914秒 0.01039秒 0.00911秒 0.00905秒 0.00938秒
pdo(2): 0.00044秒 0.00045秒 0.00037秒 0.00034秒 0.00088秒
pear::DB(2): 0.01989秒 0.02007秒 0.02300秒 0.02003秒 0.02123秒
mysql(2): 0.00943秒 0.01047秒 0.00953秒 0.00962秒 0.00942秒

サーバー側の問題もあるので、毎回安定した処理結果は得られませんでしたが、大体上表のような結果になりました。
やはりネイティブ関数は速く、mysqli関数が一番速い結果になりました。
続いて同じくネイティブ関数のmysql関数が続き、その次にPDOという結果になりました。
PDOでは、プリペアドステートメントを用いてSQLを発行したため、2回目のSQLの発行ではキャッシュが効き、劇的な速さになっています。
一番遅かったのは予想通り、PEAR::DBでした。
ネイティブ関数よりも2〜3倍遅く、PDOよりも2倍近く遅い結果となりました。
PHP用アクセラレータを導入していなければ、PEAR::DBはもっと遅くなっただろうと考えられます。


まとめ

PHP5を利用していて、DBの抽象化を行いたいのであれば、PEAR系のモジュールはやめてPDOにした方が良いと言えます。
単純なSELECT文の結果でさえ、2倍近い性能差が出ていますから当然です。

DBの抽象化を行う必要がない場合、PDOを使うかネイティブ関数を使うか迷うところですが、状況に応じて使い分けるのが良いと思います。
PDOは、対象データベースがMySQL 3.x/4.x/5.xを始め、PostgreSQL、SQLite 3、SQLite 2、FreeTDS、Microsoft SQL Server、Sybase、Firebird/Interbase 6、IBM DB2、Oracle Call Interfaceなどの大量のデータベースに対応しています。
他のDBも扱う予定があるのならば、PDOの処理だけを覚えてしまうのが簡単です。

一方、処理速度がボトルネックとなっていて、DBを変更する予定もないのであればネイティブ関数のmysqli関数でチューニングするという方向で良いと思います。
PDOは、PEAR::DBのように圧倒的に遅いわけではないので、状況に応じて選べば良いと思います。
当然、そのサーバーで扱うデータを元に、それぞれのSQLを発行して処理速度比較を計測してから決めることも重要です。

PHP5系の利点として、SimpleXML関数を使えるのが個人的に一番利点だと思っていましたが、今回の実験によりPDO 関数が使えるのも大きな利点だということがわかりました。

追記:PHP7以降の情報は「PHPでデータベースに接続するときのまとめ - Qiita」を読んでください。非常に良くまとまっています。

関連リンク

PHP5.2.1リリース
XCacheのインストールとphp用アクセラレータ比較
PHP5.2.0とeAcceleratorのインストールメモ
PEARのアップグレードメモ
PHP Accelerator インストールメモ
phpMyAdmin設置メモ