Pgpool-II 4.1 新機能: Pgpool-II によって発行される内部クエリの改善【第8回】

この記事はPgpool-II 4.1の紹介【第1回】の中のPgpool-II によって発行される内部クエリの改善について詳しく紹介します。

バージョン情報を活用した内部クエリの削減

Pgpool-IIは、クライアントから受信した問い合わせを解析するために必要な様々な情報を入手するためにPostgreSQLに内部的にクエリを発行します。第7回で解説したシェアードリレーションキャッシュは、そうしたクエリ結果のキャッシュの利用を改善するものでした。Pgpool-II 4.1では、それとは別に発行する内部クエリそのものを削減する努力をしています。その一つが、PostgreSQLのバージョン情報を活用した内部クエリの削減です。

バージョンで異なるPostgreSQLのシステムカタログへの問い合わせ

Pgpool-IIが発行する内部クエリは、主にPostgreSQLのシステムカタログを問い合わせるものです。たとえば、Pgpool-IIではあるテーブルが一時テーブルかどうか各テーブルごとに問い合わせを行います。一時テーブルを含む問い合わせはストリーミングレプリケーションのスタンバイサーバには送信できないからです。あるテーブルが一時テーブルかどうかの判断方法はPostgreSQLのバージョンで異なり、実は結構厄介です。

  • PostgreSQL 8.4と9.0では、システムカタログpg_classの”relistemp”列がtrueなら一時テーブル
  • それ以外のバージョンではスキーマが”pg_temp”なら一時テーブル

という具合です。従来は、

  1. pg_classにrelistempという列があるかどうか調べる
  2. もしなければシステムカタログpg_namespaceを調べてスキーマがpg_tempであるかどうか調べる
  3. もしrelistempがあればそれがtrueなのかfalseなのか調べる

という具合に最大2回の内部クエリ発行が必要でした。

バージョン情報を活用して内部クエリを削減

Pgpool-II 4.1では、あらかじめPostgreSQLのバージョンを調べておき、それによってpg_classのrelistempを調べるか、pg_namespaceを調べるかを判断できるので、内部クエリの発行回数を1回にすることができます。

他の内部クエリでも同様の工夫を行うことにより、従来一つのユーザからの問い合わせにつき最大内部クエリが7回ほど発行されていたのが2-3回に減らすことができました。

より効率的な一時テーブルのチェック

上の改良により、一時テーブルのチェックはかなり効率的になりましたが、それでも一時テーブルかどうか知るための内部クエリを完全になくすことはできません。そこで導入されたのがcheck_temp_tableというパラメータです。このパラメータを"trace"に設定すると、システムカタログに内部クエリを発行せずに、CREATE TEMP TABLE文がこのセッションで投入されたかどうかを追跡することによって一時テーブルかどうかの判定を行います。これにより内部クエリの発行が不要になりますが、注意することもあります。

一時テーブルの生成がPgpool-IIから見えない場合(たとえば関数やトリガの中で行われる場合)、Pgpool-IIは一時テーブルの生成を認識できません。この場合は、check_temp_tableに”catalog”を設定することにより、従来と同じシステムカタログを検索する動作になります。

終わりに

今回はPgpool-IIが発行する内部クエリの改善について解説しました。Pgpool-IIの発行する内部クエリの多さが気になる方はPgpool-II 4.1を試してみてはいかがでしょう。