PostgreSQLは,米California大学Berkley校で開発されたpostgresを源流とするオープンソースのDBMSである。ANSI SQL92に対応し,行ロック,読み取り一貫性,ストアド・プロシージャ,トリガーを実装するなど,商用DBMS製品に匹敵する機能を備える。このコラムでは,PostgreSQLの最新状況を報告していく。
PostgreSQLは,現在次期バージョンである7.4のベータ・テストを実施している。8月27日にはベータ2がリリースされており,このまま順調にテストが進めばもう1,2回ほどベータ版がリリースされたのち,リリース・キャンディデート(リリース候補版)を経て正式リリースとなるはずである。どうやら年内にはPostgreSQL7.4の正式版が入手できそうだ。
今回は,PostgreSQL7.4の主な特徴を概観してみる。
アーカイブ・ログからのデータベース復旧機能は見送り
まず悪いニュースから。
7.4で実装されることが期待されていたPoint In Time Recovery(PITR)は見送りになった。PITRとは,古くなったトランザクションログを保存しておき,万が一ディスク障害などでデータベースが破壊されたときにそこから復旧するというものだ。ほとんどの商用DBにはこの機能が付いているが,PITRがないPostgreSQLでは,こまめなバックアップや,レプリケーションで自衛する必要がある(この9月に発売されたばかりのPostgreSQL互換商用データベース「PowerGres Plus」では,アーカイブ・ログからのリカバリがサポートされている)。
VACUUMの自動実行などの新機能
PITRという大物は追加されなかったが,いつものように,多数の細かな機能追加が行われている。PostgreSQLでは,データベースの不要領域を回収する「VACUUM」を行なわずに長期間運用すると,性能が低下する場合がある。7.4では,VACUUMを自動実行する機能pg_autovacuumが追加された。そのほか,主な追加機能を以下に示す。
・INFORMATION SCHEMAの追加
・読み取り専用トランザクション
・UPDATE ... SET col = DEFAULT のサポート
・LIMIT/OFFSETで定数だけでなく,式が指定可能になった
・ステートメント・レベルのトリガのサポート
・DOMAIN CHECK制約の追加
・ALTER DOMAIN, ALTER SEQUENCEの追加
・トランザクションの外側でもカーソルが使えるようになった
・TRUNCATEでトランザクションが有効になった
・新しい配列コンストラクタ「ARRAY」の導入
GROUP BYを含むSQL処理で2倍以上高速化
7.4での性能改善を検証してみた。いくつかのSQLではっきりとわかる高速化が行われている。今回は,以下の環境でテストを行った。
ハードウェア: Let'S Note CF-W2, メモリ512MB
OS: Vine Linux 2.6
postgresql.confの設定: デフォルトのまま
PostgreSQLのバージョン: 7.3.4および2003年9月3日時点の開発中スナップショット(文中では「7.4」と表記)
GROUP BYとは,ある基準に基づいて行をグループ分けするSQLの構文である。たとえば,
SELECT avg(年齢) FROM 住民年齢統計データ GROUP BY 県; |
などとすることによって,全国の住民の年齢統計データを県ごとにグループ分けし,県別に平均年齢を求めることができる。この例からもわかるように,GROUP BYは主に統計データや販売データなどの大量データの解析によく使われる重要なSQLの機能である。7.4ではこのGROUP BYが大幅に高速化された。
ここではPostgreSQLに付属するベンチマークツールであるpgbenchで生成した10万件のデータを用いて同じSQL文を7.3.4と7.4で実行した結果を示す(試行は10回行い,最大値と最小値を除く8件のデータの平均値をとっている)。
SELECT count(*) FROM accounts GROUP BY bid; |
7.3.4 | 766.619ミリ秒 |
7.4 | 326.205ミリ秒 |
このように,2倍以上7.4の方が高速になっている。その理由を探るために,7.4で問い合わせ計画をEXPLAINを使って表示してみる。
test=# EXPLAIN SELECT count(*) FROM accounts GROUP BY bid; QUERY PLAN ---------------------------------------------------------------------- HashAggregate (cost=3140.00..3140.00 rows=1 width=4) -> Seq Scan on accounts (cost=0.00..2640.00 rows=100000 width=4) (2 rows) |
「HashAggregate」というキーワードが目新しい。HashAggregateでは非常にコストの高いソート処理が不要になるため,その分高速になっているのである。
INサブクエリ(副問い合わせ)で6倍近く高速化
GROUP BYよりもさらに高速化されたのが,SELECT ... WHERE col IN (1, 2,3...); のような形のIN副問い合わせである。ここでもpgbenchのデータを使ってSQL文を実行した結果を示す。
SELECT count(*) FROM accounts WHERE aid IN (1, 2, 3, ..., 999, 1000); |
これはINリストが1000個にもなる極端な例だが,データベース用のある種のアプリケーションはこのようなSQL文を自動生成することがある。実行時間は以下のようになった。
7.3.4 | 平均 530.209ミリ秒 |
7.4 | 平均 91.1188ミリ秒 |
6倍近く7.4の方が速いという結果が出た。問い合わせプラン自体は7.3も7.4も変わらないが,7.4では,問い合わせ実行部(executor)により細かいチューニングが施された結果,高速化した。
WHERE節にSELECTを持つINサブクエリで600倍近い性能改善
さらに劇的に高速化したのが,SELECT ... WHERE col IN (SELECT ...); のようなIN副問い合わせである。テストデータはやはりpgbenchのものを使用している。
SELECT count(*) FROM accounts WHERE aid IN (SELECT tid FROM tellers); |
7.3.4 | 平均 3108.87ミリ秒 |
7.4 | 平均 5.22875ミリ秒 |
![]() |
図1 |
![]() |
図2 |
もちろん7.3でも手動で
SELECT count(*) FROM accounts, tellers WHERE accounts.aid = tellers.tid; |
のように問い合わせを書き換えれば一応高速化は可能である。しかし,いつもこのような書き換えができるとは限らないし,手動で問い合わせを書き換えるのは煩わしい作業である。7.4でこうした心配をする必要が減るのなら,まことにうれしい限りである。
手間いらず,手軽に使える高性能データベースを目指す
PostgreSQL7.4は,新しい機能という点でははやや物足りないリリースではあるが「管理の手間がかからず,だれでも手軽に使える高性能データベース」という理想に着実に近づいている。商用DBによくある「ヒント句」のようなものには頼らず,どんなユーザでも高性能データベースの恩恵を受けることができるようにすべきであるというのがPostgreSQLの開発者の一貫した考え方だ。オープンソース・データベースらしい,こうした潔い姿勢を今後も貫いてほしい。
石井達夫(Tasuo Ishii)
■著者紹介
石井達夫(いしい・たつお)氏
1984年,SRA入社。主にUNIX関連の開発に従事するかたわら,95年からPostgreSQLのメーリング・リストを主宰。現在はオープンソースソリューション部でPostgreSQL関連のビジネス活動を技術支援。著書に『PostgreSQL完全攻略ガイド』(技術評論社),『PHPxPostgreSQLで作る最強Webシステム』(技術評論社),『PostgreSQL構築・運用ガイド』(日経BP,共著)などがある。日本PostgreSQLユーザ会理事長。