The EDB Blog
March 16, 2017

最近の Twitter による投票で、PostgreSQL V10 のお気に入りの新機能は何か? を調べてみました。 この明らかに非科学的な調査では、「改善された並列性」(37%) が「論理的リプリケーション」(32%) と「ネイティブパーティショニング」(31%) を凌ぎました。 私は、これらの機能の内どれが実際に最重要であるかについて議論するのは無駄な事だと思いますが; 本当のところ、これらの全ての機能が驚くべき機能であり、PostgreSQL 10 は素晴らしいリリースになる道を進んでいると思います。そこにはこれまでのリリースであれば目玉機能として通用したであろう、たくさんのすでにコミットされた、あるいはコミットされるかも知れない機能がありますが、このリリースではそれらは上記で述べた機能と競争しなくてはならないでしょう。

それでも、私は先に述べた投票で、改善された並列性が最も人気のある選択に残った事にがっかりしているとは言いませんが、今回のリリースで発表されるであろう、または発表されるかもしれない、いくつかの現在の、また提案中の改善についてハイライトを当ててみたいと思います。

すでにコミットされているもの

これらの改善はすでにコミットされており、ある問題のために差し戻しが必要にならない限り、PostgreSQL 10 に実装されます。

並列ビットマップ ヒープスキャン (ディリップ・クマー) 並列クエリーのドライブテーブルは、利用可能なワーカー間のスキャンをパーティショニングできる、並列性を意識したスキャン形式でスキャンされなくてはならず; PostgreSQL 9.6 では唯一の並列性を意識したスキャン形式は並列連続スキャンであったため、あなたは並列性を使うかインデックスを使うかを選択しなくてはなりませんでした。 並列ビットマップヒープスキャンでは、一つの処理がインデックスを処理し、スキャンされるべき全ヒープページを示す共有メモリー内にデータ構造を構築し、次に全ての協働処理が並列にヒープスキャンを実行可能になります。インデックススキャンを並列に実行できる事も素晴らしい事ですが、これについては将来のリリースを待たなくてはならないでしょう。

並列インデックススキャン (ラヒラ・サイド、アミット・カピラ、ロバート・ハース)、並列インデックス単一スキャン (ラフラ・サビ) インデックスアクセス方式で並列スキャンを可能にするためにインフラストラクチャーが追加されましたが、btree アクセス方式はこのインフラストラクチャーを使用するよう改造され、最適化ツールとエクスキューターは、インデックススキャンおよびインデックス単一スキャンのために、これらの能力を使用する事を学習しました。そのために、現在インデックススキャンまたはインデックス単一スキャンを使用して、ドライブテーブルがスキャンされる事が可能となっています。私は、これが実装される方法が原因で、このケースで最大限可能な並列性のレベルは、並列ビットマップヒープスキャンまたは並列連続スキャンの場合よりも、少ないのではないかと疑っています。 返される行数が巨大な場合、インデックススキャンがビットマップスキャンに負ける可能性が高い事も事実ですし、ドライブテーブルから返される行数が大きくない場合は、並列クエリーからは大きな利益は得られないのではないでしょうか。それでも、これらの変更はある種のクエリーに対しては大きな改良へと導いたのです。

集合結合 (ラシャブ・ラシア) PostgreSQL 9.6 で導入された Gather ノードは、任意の順序で全てのワーカーから結果を集めます。 ワーカーが作成したデータが特に順序を持たない場合は良いのですが、もし各ワーカーが仕分けした出力を作成している場合は、その仕分け順序を保持できる方法でこれらの結果を集めた方が良いでしょう。これが集合結合機能の目的です。 これは、プランの並列部分の結果にあえて仕分け順序を持たせるのが有利な場合、およびプランの並列部が十分な行を生成していて、Sort に続いて 通常の Gather を実行する事が高価である場合に、クエリーの速度アップを可能にします。

並列マージ結合 (ディルップ・クマー) PostgreSQL 9.6 では、プランの並列部ではハッシュ結合と入れ子ループのみが実行可能です。 PostgreSQL 10 では、プランの並列部でマージ結合も実行可能です。 ある意味でこれらは、本来の並列ハッシュ結合ではありません — なぜなら、各パーティシパントが結合の外側にある行のサブセットのみを見るのに対して、各パーティシパントは結合の内側にある各行を訪れなくてはならないためです; そうでないと、結合結果は不完全になる可能性があります。これは結合の外側の動作がパーティシパント間で分割される事を意味しますが、結合の内側の動作は各パーティシパントごとに重複します。より良い戦略が可能で、並列クエリーに関する学術文献にまとめられていますが、しかしこれは、場合によってはPostgreSQL 9.6 で可能であったものによって改善できます。それは特に並列インデックススキャンが自明な仕分けの必要なく、結果を仕分けられた順序で得られる方法を提示するためです。

サブプラン関連の改善 (アミット・カピラ) PostgreSQL 9.6 では、サブプランがリーダーからワーカーへと渡される事はなく、そのため、関連するサブクエリーとともにクエリープランに現れるどのようなテーブルも、並列処理の候補ではありませんでした。PostgreSQL 10 では、この制約はやや緩くなっています。 現在では、無相関のサブプランを持つテーブルはプランの並列部に現れます。 残念ながら無相関のサブプランを持つテーブル、あるいは InitPlan への参照は未だに並列処理に考慮される事がありません; この分野には更に相当な作業がなされる事になるでしょう。

クエリーテキストのワーカーへのパス (ラフィア・サビ) PostgreSQL 9.6 では、並列ワーカーに関連するクエリーテキストが pg_stat_activity に現れる事はありませんが、PostgreSQL 10 ではそれが現れる事になります。 同じく、もしあなたが不幸にして並列ワーカーのクラッシュに見舞われた時、その時実行されていたクエリーのクエリーテキストは、ユーザー接続されていたバックエンドと同様、レポートされます。これらの改善は監視とトラブルシューティングに役立ちます。

懸案事項

これらの改良は PostgreSQL 10に取り込まれる可能性のためすでに提出されましたが、これを書いている時点ではまだ将来のリリースに、コミットされるとも保留されるとも決定されていません。

並列 CREATE INDEX (ピーター・ゲオゲーガン) 並列処理のためのサーバー側インフラストラクチャーはクエリー同様、ユーティリティコマンドに適用される事が可能となるよう構築されていますが、まだどのような例も得られていません。 この提案されている作業は btree インデックスの作成を、3倍ほどスピードアップします。

改善された並列ハッシュ結合 (トーマス・マンロ) PostgreSQL 9.6 で、各ワーカーごとに並列でハッシュ結合を実行する唯一の方法は、ハッシュテーブルのプライベートコピーを作成する事です。 次に、全ワーカーが並列でプローブテーブルをスキャンし、それぞれが自身のハッシュテーブルを調べます。 ビルドテーブルが小さい場合はこれで大丈夫ですが、これは各ワーカーがそれ自身のハッシュテーブルへ全く無競争のアクセスを行うため、恐らくは最善の策です。 しかし、ハッシュテーブルが巨大であったり、またはビルドするのが高価な場合は、まずい戦略となります。提案される patch で、単一で共有の、また任意で並列のハッシュテーブルをワーカーによって作成可能にする事で、これを修正できます。  大部分で、この patch の有利な点はそれが結合を高速にする事ではなく、それが結合への両方のインプットがどちらかだけでなく、並列に組み立てられる事を可能にする事です。

InitPlan 値をワーカーにパス (アミット・カピラ) もし InitPlan が Gather ノードの上のクエリーにアタッチされると、リーダーの値を算出する事ができ、それを全てのワーカーに広める事ができます。 現在はこのタイプのプランは、我々が値をワーカーに渡すメカニズムを持たないため、許されていません; この patch はそのようなメカニズムを追加し、対応するプランを実現します。

並列アペンド (アミット・カピラ) 現在 Append は並列クエリーには、非常に限られた方法でしか使用できません。 パーティションされたテーブルは並列でスキャンされますが、パーティションは全て一定の形式の並列プランでスキャンされなければなりません。 上述の変更で PostgreSQL 10 の制限が PostgreSQL 9.6 の場合よりかなり緩和されますが、最速の方法でのテーブルスキャンが、インデックススキャンや非 btree インデックスなどの、ある種の非並列プランとなる可能性があります。 加えて、Append がプランの並列部に現れた場合、最初の子プランが第二の子プランの開始前に最後までスキャンされ、第3の子プランの開始前に終了する、などが続きます。 例えば異なるディスクからの I/O が並列に発生するよう、また CPU の競争を低減するために、ワーカーを拡げる事がベターな場合がしばしばあります。 この patch は、こうした問題への対処を狙うと同時に、UNION ALL クエリーが明確な方法で並列化される事を可能にするものです。

手続き型言語からの Access to Parallel クエリーを改良 (ラフィア・サビ) PostgreSQL 9.6 では PL/pgsql 手順のある種のクエリーで並列クエリーにアクセスできますが、他の手続き型言語ではそれができません。 全ての内蔵の手続き型言語にまたがる、並列クエリーへのアクセスを改善する作業が PL/pgsql 以外の言語の言語サポートを追加する事と、並列クエリーが PL/pgsql 内から使用できるシチュエーションの範囲を拡大する事の両面から進行中です。

SERIALIZABLE 時に並列クエリーを可能にする (トーマス・マンロ)  直列化可能な分離レベルは、現在並列クエリーをサポートしていません。 この制限を撤廃するために patch 類が提案されています。

ピーター・ゲオゲーガンを除いて、上述の開発者全員が EnterpriseDB に雇用されているものです。 私はこの機会に EnterpriseDB 社の経営陣に対して、PostgreSQL コミュニティにおいてこの仕事へのサポートを継続していただいている事に感謝を述べたいと思います; EnterpriseDB が達成した仕事の 100% が PostgreSQL コミュニティプロセスを通じてPostgreSQL ライセンスの下で、PostgreSQL コミュニティに提出されています。  我々は将来のリリースにもこのような貢献を続ける所存です。

私の同僚たちと私は、これらの改善の開発、テスト、ベンチマークにおいて、良い並列クエリーと悪いものを区別する事について多くの事を学びましたが、それは将来の並列クエリーの仕事の方向を決めるのに有益な事でした。 これはすでに大きな話題となっているため、私はそのトピックについて将来ブログで洞察を共有したいと思います。

どうぞ自由にコメントを残してください! 私はあなたが新しい並列クエリーの改良について何が好きで、何が嫌いか、また将来どんな機能が完成するのを期待しているか、について興味があるのです。

ロバート・M・ハースは、EnterpriseDB 社の副社長兼チーフデータベースアーキテクトです。 

この投稿記事は、もともとRobert氏の個人的なブログに掲載されていたものです。

 

robert.haas_enterprisedb.comの写真

Robert is Chief Architect, Database Server, employed at EnterpriseDB as well as a PostgreSQL Committer. Robert is an expert in OLTP query tuning, schema design, triggers and stored procedures, and internals development, as well as an experienced UNIX/Linux system administrator. Additionally,...