★PostgreSQLカンファレンス2024 12月6日開催/チケット販売中★
他のバージョンの文書 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9.6 | 9.5 | 9.4 | 9.3 | 9.2 | 9.1 | 9.0 | 8.4 | 8.3 | 8.2 | 8.1 | 8.0 | 7.4 | 7.3 | 7.2

19.7. 問い合わせ計画

19.7.1. プランナメソッド設定

以下の設定パラメータは、問い合わせオプティマイザが選択する問い合わせ計画に影響する大雑把な手法を提供します。 ある問い合わせに対してオプティマイザが選択したデフォルト計画が最適でない場合、暫定的な解決策は、これらの設定パラメータの1つを使用し、オプティマイザに異なる計画を選択するように仕向けることです。 オプティマイザが選択する計画の品質を改善するためのより良い方法には、プランナコスト定数を調節する(19.7.2を参照)、ANALYZEを手作業で実行する、default_statistics_target設定パラメータの値を大きくする、ALTER TABLE SET STATISTICSを使用して、特定の列に対して収集される統計情報を増やす、などがあります。

enable_bitmapscan (boolean)

問い合わせプランナがビットマップスキャン計画型を選択することを有効もしくは無効にします。デフォルトはonです。

enable_gathermerge (boolean)

問い合わせプランナがギャザーマージ計画型を選択することを有効もしくは無効にします。 デフォルトはonです。

enable_hashagg (boolean)

問い合わせプランナがハッシュ集約計画型を選択することを有効もしくは無効にします。 デフォルトはonです。

enable_hashjoin (boolean)

問い合わせプランナがハッシュ結合計画型を選択することを有効もしくは無効にします。デフォルトはonです。

enable_indexscan (boolean)

問い合わせプランナがインデックス走査計画型を選択することを有効もしくは無効にします。デフォルトはonです。

enable_indexonlyscan (boolean)

問い合わせプランナがインデックスオンリースキャン計画型を選択することを有効もしくは無効にします。 (11.11を参照してください) デフォルトはonです。

enable_material (boolean)

問い合わせプランナの具体化の使用を有効、または無効にします。 全体にわたって具体化を差し止めることはできませんが、この値をoffにすることにより、正確性が要求される場合を除いて、具体化ノードをプランナが挿入することを防止します。デフォルトはonです。

enable_mergejoin (boolean)

問い合わせプランナがマージ結合計画型を選択することを有効もしくは無効にします。デフォルトはonです。

enable_nestloop (boolean)

問い合わせプランナがネステッドループ結合計画を選択することを有効もしくは無効にします。 ネステッドループ結合を完全に禁止することは不可能ですが、この変数をオフにすると、もし他の方法が利用できるのであれば、プランナはその使用を行わないようになります。 デフォルトはonです。

enable_seqscan (boolean)

問い合わせプランナがシーケンシャル走査計画を選択することを有効もしくは無効にします。 シーケンシャル走査を完全に禁止することは不可能ですが、この変数をオフにすると、もし他の方法が利用できるのであれば、プランナはその使用を行わないようになります。デフォルトはonです。

enable_sort (boolean)

問い合わせプランナが明示的並び替え手順を選択することを有効もしくは無効にします。 明示的並び替えを完全に禁止することは不可能ですが、この変数をオフにすると、もし他の方法が利用できるのであれば、プランナはその使用を行わないようになります。デフォルトはonです。

enable_tidscan (boolean)

問い合わせプランナがTID走査計画型を選択することを有効もしくは無効にします。デフォルトはonです。

19.7.2. プランナコスト定数

本節で扱うコスト変数は、任意の尺度で測られます。 これらは相対的な値のみが意味を持つため、それらの値をすべて同じ係数で大きく、あるいは小さくしても、プランナの選択は結果として変わりません。 デフォルトではこれらのコスト変数はシーケンシャルなページ取り込みに基づいています。 つまり、seq_page_costを慣習的に1.0とし、他のコスト変数はそれを参考にして設定されています。 しかし望むなら、特定のマシンにおけるミリ秒単位の実行時間など、異なる尺度を使用することができます。

注記

残念ながら、コスト変数に対する理想的な値を決定する、上手く定義された方法がありません。 特定のインストレーションが受け取る問い合わせ全体を混在させたものの平均として扱うのが最善でしょう。 数回の実験のみを根拠にこの値を変更することは危険であるといえます。

seq_page_cost (floating point)

シーケンシャルな一連の取り出しの一部となる、ディスクページ取り出しに関する、プランナの推定コストを設定します。 デフォルトは1.0です。 この値は同じ名前のテーブル空間パラメータを設定することで、特定のテーブル空間の中にあるテーブルとインデックスに対して上書きできます(ALTER TABLESPACEを参照してください)。

random_page_cost (floating point)

非シーケンシャル的に取り出されるディスクページのコストに対するプランナの推測を設定します。 デフォルトは4です。 この値は同じ名前のテーブル空間パラメータを設定することで、特定のテーブル空間の中にあるテーブルとインデックスに対して上書きできます(ALTER TABLESPACEを参照してください)。

この値をseq_page_costと比較して小さくすると、システムはなるべくインデックススキャンを使用するようになります。 大きくすると、インデックススキャンが相対的に高価になります。 両方の値を増減させることで、CPUコストに対するディスクI/Oコストの重要性を変更させることができます。 これについては、後述のパラメータで説明します。

機械的ディスク記憶装置に対するランダムアクセスは通常はシーケンシャルアクセスの4倍よりもかなり高価です。 しかし、より低いデフォルト(4.0)が使用されます。というのはインデックスのついた読み取りのようなディスクに対するランダムアクセスのほとんどはキャッシュにあると想定されるからです。 このデフォルト値は、ランダムアクセスがシーケンシャルアクセスより40倍遅い一方で、ランダム読み込みの90%はキャッシュされていることが期待されるというモデルとして考えることができます。

自環境の作業負荷において、90%のキャッシュ率は誤った仮定と考えられるのであれば、ランダム記憶装置読み込みのコストをより良く反映するため random_page_cost を大きくすることができます。 反対に、データが完全にキャッシュされていると思われるのであれば、random_page_cost を小さくすることが適切です。例えば、データベースの容量がサーバのメモリより小さい場合などです。 例えばSSDのような、シーケンシャルアクセスに比べてランダム読み込みコストがあまり大きくない記憶装置の場合も、random_page_cost に対しより低い値のモデル化の方が良いでしょう。

ヒント

システムはrandom_page_costseq_page_costよりも小さな値に設定することを許しますが、そのようにすることは物理的にはおかしなことです。 しかし、データベースが完全にRAMにキャッシュされる場合、同じ値に設定することは意味を持ちます。 この場合、順序通りではないページアクセスに対するペナルティが存在しないからです。 また、多くがキャッシュされるデータベースでは、CPUパラメータに対して両値を小さく設定すべきです。 RAM内に存在するページの取り出しコストは通常よりもかなり小さくなるためです。

cpu_tuple_cost (floating point)

問い合わせ時のそれぞれの行の処理コストに対するプランナの推測を設定します。 デフォルトは0.01です。

cpu_index_tuple_cost (floating point)

インデックス走査時のそれぞれのインデックス行の処理コストに対するプランナの推測を設定します。 デフォルトは0.005です。

cpu_operator_cost (floating point)

問い合わせ時に実行される各演算子や関数の処理コストに対するプランナの推測を設定します。デフォルトは0.0025です。

parallel_setup_cost (floating point)

パラレルワーカープロセスを起動するためのコストに対するプランナの推測値を設定します。 デフォルトは1000です。

parallel_tuple_cost (floating point)

あるパラレルワーカープロセスから、1行を他のプロセスに転送するためのコストに対するプランナの推測値を設定します。 デフォルトは0.1です。

min_parallel_table_scan_size (integer)

パラレルスキャンを考慮する最小のテーブルデータのサイズを指定します。 パラレル順スキャンでは、スキャンされるテーブルのデータ量は、常にテーブルのサイズと同じです。 しかし、インデックスが使われる場合は、スキャンされるテーブルの量は通常少なくなるでしょう。 デフォルトは8メガバイト( 8MB)です。

min_parallel_index_scan_size (integer)

パラレルスキャンが考慮されるために、スキャンされなければならないインデックスデータの最小量を設定します。 通常パラレルインデックススキャンは、典型的にはインデックス全体をアクセスしないことに注意してください。 これは、関連するスキャンにより、プランナが実際にアクセスされると信じるページ数です。 デフォルトは512キロバイト(512kB)です。

effective_cache_size (integer)

単一の問い合わせで利用できるディスクキャッシュの実効容量に関するプランナの条件を設定します。 これは、インデックスを使用するコスト推定値の要素となります。 より高い値にすれば、よりインデックススキャンが使用されるようになり、より小さく設定すれば、シーケンシャルスキャンがより使用されるようになります。 このパラメータを設定する時には、PostgreSQLの共有バッファとPostgreSQLデータファイルに使用されるカーネルのディスクキャッシュの量の両方を考慮しなければなりません。 また、利用可能な領域を共有しますので、異なるテーブルに対して同時に実行される問い合わせの想定数も考慮してください。 このパラメータは、PostgreSQLで割り当てられる共有メモリの大きさには影響を与えません。また、カーネルのディスクキャッシュを予約したりもしません。 これは推定目的のみで使用されます。 同時に、システムは問い合わせの間のディスクキャッシュ内のデータの残滓を想定していません。 デフォルトは4ギガバイト(4GB)です。

19.7.3. 遺伝的問い合わせオプティマイザ

遺伝的問い合わせオプティマイザ(GEQO)はヒューリスティック(発見的)検索法を用いた問い合わせ計画を行なう演算手法です。 通常のしらみつぶしの検索演算手法で見いだされる計画よりも時として劣った計画を作成するという代償を払いますが、この手法は(多くのリレーションを結合するような)複雑な問い合わせに対し計画時間を軽減します。 より詳細は第59章を参照してください。

geqo (boolean)

遺伝的問い合わせ最適化を有効もしくは無効にします。デフォルトは有効です。 運用時には無効にしないことが通常最善です。geqo_threshold変数は、GEQOを制御するためよりきめ細かな方法を提供します。

geqo_threshold (integer)

少なくともこれだけの数のFROM項目数があるときに、問い合わせを計画するのに遺伝的問い合わせ最適化を使用します。 (FULL OUTER JOINの生成子は、FROM項目が1つだけとして計算することに注意してください。) デフォルトは12です。 もっと単純な問い合わせでは、通常の、そしてしらみつぶしの検索プランナを使用するのが最善ですが、多くのテーブルを持つ問い合わせでは、しらみつぶしの検索は非常に時間がかかり、しばしば次善の計画を実行する代償より長くなります。 従って、問い合わせの大きさに対する閾値はGEQOの使用を管理するのに便利な方法です。

geqo_effort (integer)

GEQOにおける計画時間と問い合わせ計画の品質間のトレードオフを制御します。この変数は1から10までの範囲の整数でなければなりません。 デフォルトの値は5です。値を大きくすると、問い合わせ計画作成により多くの時間を費すことになりますが、より効率的な問い合わせ計画が選択される可能性が増加します。

実際geqo_effortは直接何も行いません。それはGEQOの動作に影響を与える他の変数に対し、デフォルトの値を計算するためにのみ使用されます(以下で説明します)。もしよければ、代わりに手作業で他のパラメータを設定できます。

geqo_pool_size (integer)

GEQOで使用されるプール容量を管理します。それは遺伝的個体群内の個体数です。最低でも2つはなければならず、よく100から1000までの値が使用されます。もし(デフォルトの設定である)零に設定されると、geqo_effortおよび問い合わせの中のテーブル数に基づいて、適切な値が選択されます。

geqo_generations (integer)

GEQOで使用される世代の数を管理します。それはアルゴリズムの反復数です。最低でも1はなければならず、よくプールサイズと同じ範囲の値が使用されます。これを0に設定(デフォルトの設定)すると、適切な値がgeqo_effortに基づいて選択されます。

geqo_selection_bias (floating point)

GEQOで使用される淘汰の偏りを管理します。淘汰の偏りは個体群内の(遺伝的な)自然淘汰です。値は1.50から2.00で、2.00がデフォルトです。

geqo_seed (floating point)

結合順序検索空間にわたって、GEQOが無作為のパスを選択するために使用される乱数発生器の初期値を制御します。 値は0(デフォルト)から1までの範囲です。 値を変動させると探査される結合パスの集合が変化するため、見つかる最善のパスが良くなる場合も悪くなる場合もあります。

19.7.4. その他のプランナオプション

default_statistics_target (integer)

ALTER TABLE SET STATISTICSで列特定の目的セットの無いテーブル列に対し、デフォルトの統計対象を設定します。 より大きい値はANALYZEに必要な時間を増加させますが、プランナの予測の品質を向上させます。 デフォルトは100です。 PostgreSQLの問い合わせプランナによる統計情報の使用方法に関するより詳細な情報は、14.2を参照してください。

constraint_exclusion (enum)

問い合わせを最適化するため、テーブル制約に対しての問い合わせプランナの使用を制御します。constraint_exclusionに許容される値は、on(全てのテーブルに対し制約を検査する)、off(決して制約を検査しない)、およびpartition(継承された子テーブルおよびUNION ALL副問い合わせのみ制約を検査する)です。partitionがデフォルトです。 継承テーブルと分割されたテーブルの性能向上のためしばしば使用されます。

このパラメータが特定のテーブルに対して許される時、プランナはそのテーブルのCHECK制約で問い合わせ条件を比較し、制約と矛盾する条件のテーブルの走査を省きます。 例えば以下のようになります。

CREATE TABLE parent(key integer, ...);
CREATE TABLE child1000(check (key between 1000 and 1999)) INHERITS(parent);
CREATE TABLE child2000(check (key between 2000 and 2999)) INHERITS(parent);
...
SELECT * FROM parent WHERE key = 2400;

制約排除が有効であると、このSELECTは全くchild1000を走査せず、性能を向上させます。

現在constraint_exclusionはデフォルトで、テーブルパーティショニングを実装するためによく使用される場合のみで有効です。 すべてのテーブルを有効にすることは、計画作成において単純な問い合わせでは無視できない程の余計なオーバーヘッドをもたらします。 パーティショニングされたテーブルがない場合、完全に無効にする方が良いでしょう。

制約排除とテーブル分割についてのより進んだ情報は5.10.4を参照ください。

cursor_tuple_fraction (floating point)

検索されるカーソル行の割合のプランナの見積もりを設定します。 デフォルトは0.1です。 この設定をより小さくすると、プランナはカーソルに対し起動を高速にする計画を使用するようになりがちになります。 この場合先頭の数行の取り出しは高速になりますが、行全体を取り出す場合に時間がかかるようになる可能性があります。 この値をより大きくすると、推定時間全体がより強調されるようになります。 最大の設定である1.0の場合、カーソルは通常の問い合わせとまったく同様に計画されます。 つまり、推定時間全体のみが考慮され、先頭の行の取り出しにかかる時間は考慮されなくなります。

from_collapse_limit (integer)

プランナは、FROMリストがこの数の項目より少ない結果の場合、副問い合わせを上位の問い合わせに併合します。 より小さい値は計画時間を縮小させますが、劣った問い合わせ計画をもたらす可能性があります。 デフォルトは8です。 詳細は14.3を参照してください。

この値をgeqo_thresholdか、それ以上に設定するとGEQOプランナ使用の誘引となり、最適ではない計画をもたらします。19.7.3を参照してください。

join_collapse_limit (integer)

最終的にリストがこの項目数以下になる時、プランナは、明示的なJOIN構文(FULL JOINを除く)をFROM項目のリストに直します。 この値を小さくすれば計画作成時間は減少しますが、劣った問い合わせ計画が作成される可能性があります。

デフォルトでは、この値はfrom_collapse_limitと同じ値に設定されており、殆どの場合に適切です。 これを1に設定すると明示的なJOINの再順序付けは行われなくなります。 したがって、問い合わせで指定された明示的結合順序は、関係(リレーション)が結合される実際の順序となります。 問い合わせプランナは常に最適な結合順序を選択するとは限らないので、 上級ユーザなら暫定的にこの変数を1に設定し、明示的に希望とする結合順序を指定してもよいでしょう。 詳細は14.3を参照してください。

この値をgeqo_thresholdか、それ以上に設定するとGEQOプランナ使用の誘引となり、最適ではない計画をもたらします。19.7.3を参照してください。

force_parallel_mode (enum)

性能改善が期待できなくても、テスト目的のためにパラレルクエリを利用できるようにします。 force_parallel_modeに設定できる値は、off(性能改善が期待できるときにだけパラレルクエリを使用する)、on(安全なクエリに対しては常にパラレルクエリを強制する)、regressonと同様だが、下記のような振る舞いの変更を伴う)です。

正確に言えば、この値をonにすると、安全と見なされるすべての問い合わせ計画の上にGatherノードを追加し、クエリをパラレルワーカー上で実行するようにします。 プランナがこれによってクエリが失敗すると思わない限り、パラレルワーカーが利用できない、あるいは使用できないような場合でも、たとえばサブトランザクションの開始のように、パラレルクエリコンテキストでは許可されない操作は不許可となります。 このオプションを設定することによって、エラーとなったり、あるいは期待していなかった結果がもたらされる場合には、クエリで使用されている関数はPARALLEL UNSAFE(もしくは、PARALLEL RESTRICTED)と印を付ける必要があるかもしません。

この設定値をregressとすると、onとするのに加え、自動リグレッションテストを助けるための付加的な効果が現れます。 通常パラレルワーカーからのメッセージは、そのことを表すコンテキスト行を表示しますが、regressと設定すると、非パラレル実行と同じ出力になるように、これを抑止します。 また、プランに追加されたGatherノードは、EXPLAIN出力から隠され、offに設定したときと同じ出力が得られるようにします。