ざっくりまとめ、その後自分でやってみたことも含む、ほぼパクリ
mysqlnd 徹底解説 do_akiさん
mysqlndについて
MySQL client libraryはたくさん(ZendDB、PEAR_DB…)あるが、必ず
・mysql extension:php4の時代から使えた古くからある拡張
・mysqli extension:mysql 拡張を刷新する形でphp5から利用可能なモジュール
・pdo extension:それ自身がDB 抽象層であり、配下に多くの DBMS に対応したドライバが存在、そのなかのひとつがmysql
を呼び出している
これらがMySQLと直接やり取りするかといえばそうでもなく
mysqlnd / libmysql → アクセスやプロトコル判断など
mysql / mysqli / pdo → 実際に接続
となり、詳しくは下図
mysqlnd vs libmysql
・libmysqlはMySQL側が用意しているライブラリで、MySQL利用者に対してC言語レベルでのAPIを提供する、Oracle(MySQL AB)からある枯れた技術、しかしGPLv2ライセンス
・mysqlndはZend Engine内に存在する。MySQL Native Driverという、PHPの拡張モジュールとして実装された、MySQLのネイティブクライアント
比較的新しくmysql4.1以前には接続できない
またlibmysqlと違い、my.cnfを読み込まないため、設定によっては文字コードで影響があるかも。プラグイン(mysqlnd_ms)でロードバランシング可能、問題なく動作するらしい
php5.4移行はmysqlndがデフォルトとなり、libmysqlはオプションとなった
(libmysqlは非推奨となったわけではない)
root@hostname:/etc/apt# php -i | grep mysqlnd Additional .ini files parsed => /etc/php5/cli/conf.d/10-mysqlnd.ini, Client API version => mysqlnd 5.0.10 - 20111026 - $Id: b0b3b15c693b7f6aeb3aa66b646fee339f175e39 $ Client API library version => mysqlnd 5.0.10 - 20111026 - $Id: b0b3b15c693b7f6aeb3aa66b646fee339f175e39 $ mysqlnd mysqlnd => enabled Version => mysqlnd 5.0.10 - 20111026 - $Id: b0b3b15c693b7f6aeb3aa66b646fee339f175e39 $ Loaded plugins => mysqlnd,example,debug_trace,auth_plugin_mysql_native_password,auth_plugin_mysql_clear_password mysqlnd statistics => Client API version => mysqlnd 5.0.10 - 20111026 - $Id: b0b3b15c693b7f6aeb3aa66b646fee339f175e39 $
パフォーマンスについて
メモリ使用量はmysqlndのほうが少ない
mysqlndについてはmysqli/pdoを経由しないため、メモリ使用量が半分になる
memory_get_usageではmysqli/pdoでのメモリ使用量は計上するが、libmysqlにてのメモリを計上しないため、メモリ使用量が変わらないようにみえる
ただしmysqlndについて、大きなテーブルを乗せるとメモリ使用長が大きくなるため注意
これは仕様とされており、php5.6からは回避可能、しかしmysqliを利用する必要がある
どちらが早いかやってみた
php5-mysql vs php5-mysqlnd
root@hostname:/usr/local/src# wget -d http://php5.up.seesaa.net/web/T01Prefecture.zip ... root@hostname:/usr/local/src# unzip T01Prefecture.zip Archive: T01Prefecture.zip inflating: T01Prefecture.sql root@hostname:/usr/local/src# mysql -uroot SampleDB050 < T01Prefecture.sql root@hostname:/usr/local/src# cat /var/www/htdocs/index.php <?php $url = "localhost"; $user = "root"; $pass = ""; $db = "SampleDB050"; $start = microtime(true); $max = 1000; for($i = 0; $i < $max; $i++) { // MySQLへ接続する $link = mysql_connect($url,$user,$pass) or die("MySQLへの接続に失敗しました。"); // データベースを選択する $sdb = mysql_select_db($db,$link) or die("データベースの選択に失敗しました。"); // クエリを送信する $sql = "SELECT * FROM T01Prefecture"; $result = mysql_query($sql, $link) or die("クエリの送信に失敗しました。<br />SQL:".$sql); //結果セットの行数を取得する $rows = mysql_num_rows($result); //結果保持用メモリを開放する mysql_free_result($result); // MySQLへの接続を閉じる mysql_close($link) or die("MySQL切断に失敗しました。"); } $end = microtime(true); $tm = $end - $start; echo $tm; ?> ##### 実行したところphp5-mysqlが0.5秒前後、php5-mysqlndが0.7秒前後とphp5-mysqlが早いという切ない結果に終わった おそらく接続方法(mysql_connect)によるものだと思われる ##### root@hostname:/usr/local/src# cat /var/www/htdocs/index2.php <?php $url = "localhost"; $user = "root"; $pass = ""; $db = "SampleDB050"; $start = microtime(true); $max = 1000; for($i = 0; $i < $max; $i++) { // MySQLへ接続する $mysqli = new mysqli($url,$user,$pass,$db); if (mysqli_connect_error()) { die('接続失敗です。'.mysqli_connect_error()); } // MySQLへの接続を閉じる $mysqli->close(); } $end = microtime(true); $tm = $end - $start; echo $tm; ?> ##### 実行したところphp5-mysqlが0.30秒前後、php5-mysqlndが0.35秒前後とphp5-mysqlが少し早いという切ない結果に終わった PG力のなさが出ているため、また機会があれば試す #####
参考URL
MySQL と PHP の間を詳しく見てみる
http://d.hatena.ne.jp/do_aki/20111214/1323831558