★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

18.7. 問い合わせ計画

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

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

enable_bitmapscan (boolean)

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

enable_hashagg (boolean)

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

enable_hashjoin (boolean)

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

enable_indexscan (boolean)

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

enable_indexonlyscan (boolean)

問い合わせプランナがインデックスオンリースキャン計画型を選択することを有効もしくは無効にします。デフォルトは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です。

18.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 を引き下げることが適切です。例えば、データベースがサーバメモリより小さい場合などです。 例えば半導体ドライブのような、逐次アクセスに相対して記憶装置が低いランダム読み込みコストの場合、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です。

effective_cache_size (integer)

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

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

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

geqo (boolean)

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

geqo_threshold (integer)

少なくともこれだけの数のFROM項目数で問い合わせを計画するのに遺伝的問い合わせ最適化を使用します。 (FULL OUTER JOINの生成子は、1つのFROM項目として計算することに注意してください。)デフォルトは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までの範囲です。 値を変動させると探査される結合パスの集合を変化させ、それが見つかっているより良いか、より悪い最善のパスとなる可能性があります。

18.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. 明示的なJOIN句でプランナを制御するを参照してください。

この値をgeqo_thresholdか、それ以上に設定するとGEQOプランナ使用の誘引となり、最適ではない計画をもたらします。18.7.3. 遺伝的問い合わせオプティマイザを参照してください。

join_collapse_limit (integer)

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

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

この値をgeqo_thresholdか、それ以上に設定するとGEQOプランナ使用の誘引となり、最適ではない計画をもたらします。18.7.3. 遺伝的問い合わせオプティマイザを参照してください。