postgresql.confの変更を検討すべき項目
PostgreSQLの設定ファイルである「postgresql.conf」は、前回の「OSS-DB入門 #08 バックアップ・リストア」でも出てきましたが、パフォーマンスの観点から見ると初期設定値のままではハードウェアの性能を活かしきれない可能性があります。代表的なパラメータを以下に紹介しますので、利用用途に応じて見直してみてください。
●メモリー関連
・shared_buffers
共有バッファサイズを指定します。(デフォルト値は32MB)
データベースからデータを取得する際には一旦ハードディスクから共有バッファに読み込まれ、再度同じデータにアクセスがあった場合には共有バッファからデータを取得することができます。
メモリーよりも速度の遅いハードディスクにアクセスする回数を減らすことができる為、なるべく多くのデータが共有バッファに載っている状態がパフォーマンスの観点から望ましいと言えます。
共有バッファサイズの設定値は物理メモリーサイズの4分の1程度が目安とされています。例えば4GBのメモリーを搭載したマシンの場合は1GBとなります。
あまりに大きな値を設定してしまうと、他のプロセスが使用するメモリーを圧迫してしまい、データベース全体として速度劣化を引き起こす可能性があります。
・work_mem
内部並び替えとハッシュテーブル操作が使用するメモリーサイズを指定します。(デフォルト値は1MB)ORDER BYによるソートやテーブルの結合、集約といった複雑な問い合わせを行う場合に使用されます。設定した値は同時に複数実行される問い合わせ毎に使用される為、実際に消費されるメモリーサイズは設定値の数倍になりますので、大きな値を設定するとメモリーが足りずにスワップが発生してしまう可能性があります。設定可能な最大値は物理メモリーサイズからshared_buffersのサイズを引いた値をmax_connectionsで割った値となります。
●WAL関連
・wal_buffers
WALバッファサイズを設定します。(デフォルト値はshared_buffersの1/32のサイズ)WALバッファとはWALログをディスクに書き出すまで保持しておくバッファです。このバッファのサイズを大きく設定すれば、WALバッファが一杯になったのでディスクへ書き出す、という状態になることを減らすことができます。
・checkpoint_segments
チェックポイントの処理を実行するタイミングをWALセグメントの数で設定します。(デフォルト値は3)チェックポイントとはデータの挿入や変更の内容を保持しているWALログからディスクへ書き出す処理で、大量のディスクI/Oが発生する為、コストの高いものです。1セグメントのWALログファイルのサイズは16MBです。デフォルト値の3の場合は48MB分のWALログが溜まったタイミングでチェックポイントを実行することになります。この設定値を大きくしてディスクへ書き込む頻度を減らすことで性能を向上させることができます。その代わりにWALログファイルの数が増えることになりますので、ハードディスクには十分な空き容量が必要です。また、リカバリーを行う際にも時間がかかるようになります。※WALについては本連載の「第8回 バックアップ・リストア」のPITRの項、OSS-DB道場の「第14回 トランザクションログ」に説明がありますので参照してください。
・checkpoint_timeout
チェックポイントの処理を実行するタイミングを設定しますが、こちらは時間間隔で設定します。(デフォルト値は5m)
デフォルト値の5分よりも長い間隔とすることで、上記のcheckpoint_segmentの値を大きくした場合と同様にディスクへの書き込み頻度を減らします。
インデックス
100000件のサンプルデータを投入するSQLファイルを用意しましたので、テーブルを作ったら以下のファイルをダウンロードしてデータをロードしてください。
※少々大きいのでzip圧縮してあります。解凍したsqlファイルからサンプルデータをロードする方法は「第5回 SQL基礎I 3.データの準備」を参照してください。
きちんとデータが入っているかを確認してみましょう。
以下のSQL文を実行して件数を見てみます。
SELECT COUNT(*) FROM sales;
赤枠の部分に「Seq Scan on sales」とあります。
これはsalesテーブルを順読みして検索しますよ、という意味です。また、この問い合わせのコストは1918と見積もられています。
※コストの単位は秒ではありませんので注意してください。
次にインデックスを追加して同じように見てみます。
インデックス作成の基本的な構文は以下の通りです。
CREATE INDEX インデックス名 ON テーブル名 (列名);
他にも様々なパラメータやオプション、アクセスメソッドがあるので、用途に応じてより細かく指定することもできます。
公式ドキュメントに詳細な記載がありますので興味のある方は参照してください。
http://www.postgresql.jp/document/9.1/html/indexes.html
salesテーブルの列idに対して検索を行うので以下のSQL文でインデックスを作成します。
CREATE INDEX sales_idx ON sales (id);
最後に
執筆:
市脇 康二 氏(OSS-DB Gold認定者)株式会社オークニージオソリューション事業部 マネージャー
PostGISを含めたFOSS4G(Free Open Source Software for Geospatial)ソフトウェアを活用し、地図やGPS等の位置情報を組み合わせたアプリケーションやサービスの設計・開発に従事。
サービスプラットフォームがクラウドへ、利用シーンがモバイルへと広がりを見せる中、位置情報の更なる活用シーンを模索中。
アドバイザー:
森 亮 氏 株式会社オークニー代表取締役
2002年にオークニーを設立し、代表取締役に就任。マッピング・ GIS・LBS・ITS関連プロジェクトのビジネスコンサルティングを経て、現在は会社経営の傍ら、『入門Webマッピング』(Tyler Mitchell原著;オライリー・ジャパン発行)の翻訳、Open Source Geospatial財団日本支部の代表者を務めるなど、FOSS4G(オープンソース地理空間ソフトウェア)の普及活動に取り組んでいる。
監修:
松田 神一
© EDUCO All Rights Reserved.