MySQL vs Postgres パフォーマンステスト | 株式会社ネーブルス代表取締役福田一成の公式ブログ

MySQL vs Postgres パフォーマンステスト

システム屋さんであればご存知のフリーのデータベース

MySQLとPostgresですが、さて、どっちが良いだろうと判断できない

状態ではありませんか?慣れているからと何となく使っていたりします。


それぞれの機能では特徴があり、皆さんご存知かと思いますが、

PL/SQLの真似なのか、PL/pglSQLが使えるPostgres。

処理が早いMyISAMを使うMySQL。

ただ、MyISAMは、コミット、ロールバックが使用できないです。


本日は、

MySQLには有利になってしまう事が安易に予想される

パフォーマンステストの結果をご紹介いたします。

実際どれだけ早いのか測定してみました。

今回は、インサートテスト。


環境は、

CPUが、Athron XP 2500+

メモリが、255M

ハードディクスが、8G

ちょ~オールドマシンで

OSは、CentOS5 kernel2.6.18

MySQLは、5.0.45

Postgresは、8.1.11

PHPが、5.1.6

何れもインストール時に入っていたバージョンを使用しました。


実験は、それぞれに同じテーブルを作成し

PHPによりループで以下のレコード数のインサートを行います。


company_mstには、10万件

department_mstには、50万件

person_mstには、250万件


実行は、コンソール上よりPHPのスクリプトで実行。

(テーブルとプログラムは、このブログの一番下を参照)


ちなみにMySQLは、MyISAMとInnoDBの両方で行ってみました。


さて、結果です。

(ブログでの表組みの方法が分からないので以下ですみません。)


注:単位は、秒です。


               MyISAM       InnoDB       Postgres


company_mst        21           644          771


department_mst      116          3,111         4,048


person_mst         704          16,912        25,154



予想通りにMyISAMの圧勝です。圧倒的に早いです。

以前に大量のデータをインポートするようなシステムを作りましたが、

MySQLのMyISAMを使用しました。パフォーマンスが高いと聞いてましたが

どれ程のものかは実測していなかった事もあり、今回、測定しました。

MyISAMを選んでおいて正解だったようです。

ただし、インポート時の失敗によるロールバックは出来ないので

仕組みを考える必要があります。使用には注意が必要です。

次回、また、インサートしたデータを使用して

色々な実験をしようと思っています。



実験に使用したプログラム(MySQL用)

<?
require_once "common.inc.php";

$start_time = microtime(true);
$con_string = "host=".$server." dbname=".$db." user=".$user." password=".$pass;
$con = mysql_connect($server, $user, $pass);
if (!$con) {
echo "Connection Error";
exit();
}
mysql_select_db($db);
for ($id = 1; $id <= 100000; $id ++) {
$date = date("Y-m-d H:i:s");
$query = "insert into company_mst values ('".$date."', 'hosoya', NULL, NULL, 0, NULL, ".$id.", '株式会社吉岡', 'ヨシダ', '1001000', '東京都中央区中央1-2-3中央ビル12階', '0303030303', '0303030304', 'miyata@xxxxxx.co.jp' , 0)";
$ret = mysql_query($query);
if (!$ret) {
echo "Query Error";
exit();
}
}
mysql_close($con);
$finish_time = microtime(true);
echo "company_mst insertテスト\n";
echo "start=".$start_time."\n";
echo "end=".$finish_time."\n";
$id --;
echo "レコード数=".$id."\n";
echo "完了しました\n";
$time = $finish_time - $start_time;
echo "処理時間は、".$start_time."~".$finish_time."=".$time."秒です。\n";

?>



実験に使用したテーブル構造(MySQL)

--
-- テーブルの構造 `company_mst`
--

CREATE TABLE IF NOT EXISTS `company_mst` (
`rec_ins_date` datetime NOT NULL,
`rec_ins_id` varchar(16) NOT NULL,
`rec_upd_date` datetime default NULL,
`rec_upd_id` varchar(16) default NULL,
`upd_count` int(11) NOT NULL,
`exp` varchar(256) default NULL,
`company_id` int(11) NOT NULL,
`company_name` varchar(256) NOT NULL,
`company_name_kana` varchar(256) NOT NULL,
`zip_code` varchar(7) default NULL,
`addres` varchar(256) default NULL,
`tel` varchar(11) default NULL,
`fax` varchar(11) default NULL,
`mail` varchar(256) default NULL,
`delete_flag` tinyint(1) NOT NULL default '0',
PRIMARY KEY (`company_id`)
) ENGINE=MyISAM DEFAULT CHARSET=ujis;

-- --------------------------------------------------------

--
-- テーブルの構造 `department_mst`
--

CREATE TABLE IF NOT EXISTS `department_mst` (
`rec_ins_date` datetime NOT NULL,
`rec_ins_id` varchar(16) NOT NULL,
`rec_upd_date` datetime default NULL,
`rec_upd_id` varchar(16) default NULL,
`upd_count` int(11) NOT NULL default '0',
`exp` varchar(255) default NULL,
`department_id` int(11) NOT NULL,
`company_id` int(11) NOT NULL,
`department_name` varchar(255) NOT NULL,
`department_name_kana` varchar(255) NOT NULL,
`zip_code` varchar(7) default NULL,
`address` varchar(256) default NULL,
`tel` varchar(11) default NULL,
`fax` varchar(11) default NULL,
`mail` varchar(255) default NULL,
`delete_flag` tinyint(1) NOT NULL default '0',
PRIMARY KEY (`department_id`),
KEY `company_id` (`company_id`)
) ENGINE=MyISAM DEFAULT CHARSET=ujis;

-- --------------------------------------------------------

--
-- テーブルの構造 `person_mst`
--

CREATE TABLE IF NOT EXISTS `person_mst` (
`rec_ins_date` datetime NOT NULL,
`rec_ins_id` varchar(16) NOT NULL,
`rec_upd_date` datetime default NULL,
`rec_upd_id` varchar(16) default NULL,
`upd_count` int(11) NOT NULL default '0',
`exp` varchar(255) default NULL,
`person_id` int(11) NOT NULL,
`company_id` int(11) NOT NULL,
`department_id` int(11) NOT NULL,
`person_name` varchar(64) NOT NULL,
`person_name_kana` varchar(64) NOT NULL,
`position_id` int(11) default NULL,
`tel` varchar(11) default NULL,
`fax` varchar(11) default NULL,
`cellular` varchar(11) default NULL,
`delete_flag` tinyint(1) NOT NULL default '0',
PRIMARY KEY (`person_id`),
KEY `company_id` (`company_id`),
KEY `department_id` (`department_id`)
) ENGINE=MyISAM DEFAULT CHARSET=ujis;


セレクトテスト:MySQL vs Postgres パフォー…