From 0c03e46bef57d4bbc88191a3b68028cfb271c292 Mon Sep 17 00:00:00 2001 From: Higuchi Daisuke <20634318+higuchi-daisuke@users.noreply.github.com> Date: Wed, 12 Nov 2025 03:12:12 +0000 Subject: [PATCH 1/3] Update doc/src/sgml/indices.sgml for 18.0. --- doc/src/sgml/indices.sgml | 62 ++++++++++++--------------------------- 1 file changed, 19 insertions(+), 43 deletions(-) diff --git a/doc/src/sgml/indices.sgml b/doc/src/sgml/indices.sgml index 3c0b216518a..69b5eaf8d42 100644 --- a/doc/src/sgml/indices.sgml +++ b/doc/src/sgml/indices.sgml @@ -723,24 +723,12 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); the generated constraint can be used in conjunction with a later column constraint from the query predicate). --> -《マッチ度[52.363636]》複数列に対するB-treeインデックスをインデックス対象列の任意の部分集合を含む問い合わせ条件で使用することができます。 -しかし、先頭側の(左側)列に制約がある場合に、このインデックスはもっとも効率的になります。 -正確な規則は、先頭側の列への等価制約、および、等価制約を持たない先頭列への不等号制約がスキャン対象のインデックス範囲を制限するために使用されます。 -これらの列の右側の列に対する制約は、このインデックス内から検査されます。 -ですので、テーブルアクセスを適切に抑えますが、スキャンされるインデックスの範囲を減らしません。 -例えば、(a, b, c)に対するインデックスがあり、WHERE a = 5 AND b >= 42 AND c < 77という問い合わせ条件があったとすると、 -a = 5かつb = 42を持つ項目を先頭に、a = 5となる最後の項目までのインデックスをスキャンしなければなりません。 -c >= 77を持つインデックス項目は飛ばされますが、スキャンを行わなければなりません。 -このインデックスは原理上、 aに対する制約を持たず、bあるいはcに制約に持つ問い合わせでも使用することができます。 -しかし、インデックス全体がスキャンされますので、ほとんどの場合、プランナはインデックスの使用よりもシーケンシャルテーブルスキャンを選択します。 -《機械翻訳》複数列B-ツリーインデックスは、問い合わせの列の任意のサブセットを含むインデックス条件で使用できますが、インデックスは先頭(左端)の列に制約がある場合に最も効率的です。 -正確なルールは、先頭の列に対する等式制約、つまり等式制約を持たない最初のカラムに対するプラスの不等式制約が、スキャンされるインデックスの部分を制限するために常に使用されるということです。 -これらの列の右側の列に対する制約はインデックスでチェックされるため、常にテーブルへの訪問を適切に保存しますが、スキャンする必要のあるインデックスの部分を必ずしも減らすとは限りません。 -B-ツリーインデックススキャンがスキップスキャン最適化を効果的に適用できる場合は、インデックス検索を繰り返してインデックスをナビゲートするときに、すべてのカラム制約を適用します。 -これにより、1つまたは複数の列(インデックスからの最下位のの前)に従来の等式がない場合でも、読み取られるインデックスの部分を減らすことができます。 -は、内部的に動的等式を生成することによって機能します。 -これは、内のすべての可能な値に一致します(ただし、に由来する等式を持たないが与えられた場合にのみ、生成されたが単位からの後の割引とともにで使用できる場合にのみ)。 -インデックスカラムスキップ制約問い合わせ述語制約問い合わせ制約問い合わせ制約スキャンカラム制約カラム論理積述語述語カラム +複数列に対するB-treeインデックスは、インデックス対象列の任意の部分集合を含む問い合わせ条件で使用できますが、もっともインデックスの効率が良いのは、先頭(左側)の列に制約がある場合です。 +正確な規則は、先頭の列に対する等価制約、および等価制約を持たない先頭の列に対する不等式制約は、常にスキャン対象のインデックス範囲を制限するために使用されるということです。 +これらの列の右側の列に対する制約はインデックスで検査されるため、常にテーブルへのアクセスを適切に抑えますが、必ずしもスキャンしなければならないインデックスの範囲を減らすわけではありません。 +B-treeインデックススキャンでスキップスキャン最適化を効果的に適用できる場合は、インデックス検索を繰り返してインデックスを辿るときに、すべての列制約が適用されます。 +これにより、(問い合わせの述語に含まれるもっとも重要度の低いインデックス列より前に位置する)1つまたは複数の列に従来の等価制約がない場合でも、読まなけらばならないインデックスの範囲を減らすことができます。 +スキップスキャンは、インデックス列において取り得るすべての値と一致する動的な等価制約を内部的に生成することで機能しています(ただし、問い合わせの述語に含まれる等価制約のない列に対してのみ適用され、かつ生成された制約が問い合わせの述語に含まれる後続の列制約と組み合わせて使用できる場合に限ります)。 @@ -759,10 +747,10 @@ B-ツリーインデックススキャンがスキップスキャン最適化を then the entire index will have to be scanned, so in most cases the planner will prefer a sequential table scan over using the index. --> -《機械翻訳》例では、インデックスon (x, y)、および問い合わせ条件WHERE y = 7700、B-ツリーインデックススキャンはスキップスキャン最適化を適用できる場合があります。 -これは一般に、問い合わせプランナが、テーブルで利用可能なインデックスが与えられた場合、反復WHERE x = N AND y = 7700可能性のあるすべての値Nまたは実際にインデックスに格納されているすべてxの値の検索が可能な最速のアプローチであると想定している場合に発生します。 -このアプローチは一般に、明確なx値が非常に少ないため、プランナがインデックスの大部分に対してスキャンからスキップを想定している場合にのみ使用されます(リーフページの大部分には関連するタプルが含まれていない可能性があるため)。 -明確なx値が多数ある場合は、インデックス全体をスキャンする必要があるため、ほとんどの場合、プランナはインデックスよりシーケンシャルテーブルスキャンを優先します。 +たとえば、(x, y)に対するインデックスと問い合わせ条件WHERE y = 7700では、B-treeインデックススキャンでスキップスキャン最適化を適用できる場合があります。 +これは通常、クエリプランナがそのテーブルで使用可能なインデックスを考慮した時に、WHERE x = N AND y = 7700の検索を、Nで取り得るすべての値(または実際にインデックスに格納されているすべてのxの値)に対して繰り返す方法が最速であると想定している場合に発生します。 +この方法は通常、xの個別値が非常に少なく、ほとんどのインデックスをスキップしてスキャンする(ほとんどのリーフページには関連するタプルが含まれないため)とプランナが期待する場合にのみ採用されます。 +xの個別値が多い場合、インデックス全体のスキャンが必要になる状況になりうるため、ほとんどの場合プランナはインデックスを使用するよりもシーケンシャルスキャンを好みます。 @@ -784,11 +772,10 @@ B-ツリーインデックススキャンがスキップスキャン最適化を index where the first tuple a = 5 AND b = N + 1 appears). --> -《機械翻訳》スキップスキャン最適化は、問い合わせツリーからの少なくともいくつかの有用な制約を有するB-述語スキャン中に選択的に適用することもできる。 -例の場合、インデックスon (a, b, c)および問い合わせ条件が指定されている場合、インデックスはa=5およびb=42の最初のエントリからa=5の最後のエントリまでスキャンする必要がある場合があります。 -c>=77のインデックスエントリはテーブルレベルでフィルタする必要はありませんが、インデックス内でスキップに利益をもたらす場合とそうでない場合があります。 -スキップが行われると、スキャンは新しいインデックス検索を開始して、現在a=5およびb=Nグループ化の末尾(つまり、最初のタプルa = 5 AND b = N AND c >= 77が表示されるインデックス内の位置)から、次のそのような(つまり、最初のa = 5 AND b = N + 1が表示される内の位置)に自分自身を再配置します。 -タプルグループ化スタートインデックスWHERE a = 5 AND b >= 42 AND c < 77 +スキップスキャンの最適化は、問い合わせの述語に有用な制約が少なくともいくつかあるB-treeスキャン中に、選択的に適用することもできます。 +たとえば、(a, b, c)にインデックスがあり、WHERE a = 5 AND b >= 42 AND c < 77という問い合わせ条件がある場合、インデックスはa = 5およびb = 42の最初のエントリからa = 5の最後のエントリまでスキャンする必要があるかもしれません。 +c >= 77のインデックスエントリはテーブルレベルでフィルタリングする必要はありませんが、インデックス内でスキップすると効果がある場合とない場合があります。 +スキップが行われると、スキャンは新しいインデックス検索を開始し、現在のa = 5とb = Nのグループの末尾(つまり、a = 5 AND b = N AND c >= 77の最初のタプルが現れるインデックスの位置)から、次のグルーピングの開始位置(つまり、a = 5 AND b = N + 1の最初のタプルが現れるインデックスの位置)まで位置を変更します。 @@ -1107,32 +1094,21 @@ CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST); others, you'd probably settle for creating just the two indexes that best match the common types. --> -《マッチ度[81.438999]》もっとも単純なアプリケーション以外のほとんどすべてのアプリケーションでは、インデックスの有用な組み合わせはいろいろあります。 +もっとも単純なアプリケーション以外のほとんどすべてのアプリケーションでは、インデックスの有用な組み合わせはいろいろあります。 このため、データベース開発者は妥協点を探してどのようなインデックスを提供するかを決定しなければなりません。 複数列インデックスが最善な場合がありますし、別々のインデックスを作成し、インデックスの組み合わせ機能に依存する方が優れている場合もあります。 例えば、作業にx列のみを含む場合とy列のみを含む場合、両方の列を含む場合が混在する問い合わせが含まれる場合、xyに対し、別個に2つのインデックスを作成し、両方の列を使用する問い合わせを処理する時にインデックスの組み合わせに依存することを選ぶことができます。 また、(x, y)に対する複数列インデックスを作成することもできます。 両方の列を含む問い合わせでは、通常このインデックスの方がインデックスの組み合わせよりも効率的です。 -しかし、で説明した通り、yのみを含む問い合わせではほとんど意味がありません。 -従って、このインデックスのみとすることはできません。 -複数列インデックスとyに対する別のインデックスの組み合わせがかなりよく役に立ちます。 +しかし、で説明した通り、yのみを含む問い合わせはあまり有用ではありません。 +どの程度有用かどうかは、B-treeインデックスのスキップスキャン最適化がどれほど効果的か次第です。 +xの個別値が数百個以下である場合、スキップスキャンはyの値をかなり効率的に検索するでしょう。 +(x, y)に対する複数列インデックスとyに対する別のインデックスの組み合わせもかなりよく役に立ちます。 xのみを含む問い合わせでは、複数列インデックスを使用することができます。 しかし、これはより大きくなりますので、x のみインデックスよりも低速になります。 最後の別方法は、3つのインデックスすべてを作成することです。 しかしこれはおそらく、テーブルの検索頻度が更新頻度よりもかなり高く、3種類の問い合わせすべてが良く使用される場合のみ合理的です。 問い合わせの中の1つの頻度が他よりも少なければ、おそらく良く使用される種類にもっとも合うように2つだけインデックスを作成した方がよいでしょう。 -《機械翻訳》最も単純なアプリケーションを除くほとんどのアプリケーションでは、有用なインデックスのさまざまな組み合わせがあり、データベースの開発者はどのインデックスを提供するかを決定するためにmakeのトレードオフを行う必要があります。 -複数列のインデックスがベストである場合もありますが、個別のインデックスを作成してインデックスの組み合わせの機能に依存する方がよい場合もあります。 -例では、カラムのみxカラムのみy両方の列を含む場合もあるを含む問い合わせが混在しているワークロードの場合、xyの両方の列を含む場合もあるに対して2つの個別のインデックスを作成することを選択できます。 -(x, y)の両方の列を含む問い合わせをプロセスするためにインデックスの組み合わせに依存します。 -に複数列インデックスを作成することもできます。 -このインデックスは通常、両方の列を含む問い合わせに対してインデックスの組み合わせよりも効率的ですが、で説明したように、yのみを含む問い合わせに対してはあまり有用ではありません。 -どの程度有用であるかは、B-ツリーインデックススキップスキャン最適化がどれだけ効果的であるかに依存します。 -xが数百を超える異なる値を持たない場合、スキップスキャンは合理的に効率的に特定のy値実行の値を検索します。 -(x, y)のインデックスとyの個別のの組み合わせも合理的によく機能します。 -xのみを含む問い合わせに対しては、のを使用できますが、これはx単独のよりも大きく、したがって低速になります。 -最後の選択肢は3つのインデックスすべてを作成することですが、これはおそらく、更新されるよりもはるかに頻繁に検索され、の3つのタイプすべてが一般的である場合にのみ合理的です。 -マッチ複数列問い合わせインデックステーブルベストmakeインデックスインデックス問い合わせ複数列 From 1049b0e99c60e88a1a9c3975b9384dbe81300fac Mon Sep 17 00:00:00 2001 From: Higuchi Daisuke <20634318+higuchi-daisuke@users.noreply.github.com> Date: Wed, 12 Nov 2025 12:16:26 +0000 Subject: [PATCH 2/3] Update based on copilot comments --- doc/src/sgml/indices.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/sgml/indices.sgml b/doc/src/sgml/indices.sgml index 69b5eaf8d42..80af335d3d3 100644 --- a/doc/src/sgml/indices.sgml +++ b/doc/src/sgml/indices.sgml @@ -727,7 +727,7 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); 正確な規則は、先頭の列に対する等価制約、および等価制約を持たない先頭の列に対する不等式制約は、常にスキャン対象のインデックス範囲を制限するために使用されるということです。 これらの列の右側の列に対する制約はインデックスで検査されるため、常にテーブルへのアクセスを適切に抑えますが、必ずしもスキャンしなければならないインデックスの範囲を減らすわけではありません。 B-treeインデックススキャンでスキップスキャン最適化を効果的に適用できる場合は、インデックス検索を繰り返してインデックスを辿るときに、すべての列制約が適用されます。 -これにより、(問い合わせの述語に含まれるもっとも重要度の低いインデックス列より前に位置する)1つまたは複数の列に従来の等価制約がない場合でも、読まなけらばならないインデックスの範囲を減らすことができます。 +これにより、(問い合わせの述語に含まれるもっとも重要度の低いインデックス列より前に位置する)1つまたは複数の列に従来の等価制約がない場合でも、読まなければならないインデックスの範囲を減らすことができます。 スキップスキャンは、インデックス列において取り得るすべての値と一致する動的な等価制約を内部的に生成することで機能しています(ただし、問い合わせの述語に含まれる等価制約のない列に対してのみ適用され、かつ生成された制約が問い合わせの述語に含まれる後続の列制約と組み合わせて使用できる場合に限ります)。 From ae4bbcf248e0a5651fc2787eb694e7319b045658 Mon Sep 17 00:00:00 2001 From: Higuchi Daisuke <20634318+higuchi-daisuke@users.noreply.github.com> Date: Thu, 20 Nov 2025 12:05:50 +0000 Subject: [PATCH 3/3] Update based on review comments --- doc/src/sgml/indices.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/sgml/indices.sgml b/doc/src/sgml/indices.sgml index 80af335d3d3..5bb4489f2ef 100644 --- a/doc/src/sgml/indices.sgml +++ b/doc/src/sgml/indices.sgml @@ -748,7 +748,7 @@ B-treeインデックススキャンでスキップスキャン最適化を効 will prefer a sequential table scan over using the index. --> たとえば、(x, y)に対するインデックスと問い合わせ条件WHERE y = 7700では、B-treeインデックススキャンでスキップスキャン最適化を適用できる場合があります。 -これは通常、クエリプランナがそのテーブルで使用可能なインデックスを考慮した時に、WHERE x = N AND y = 7700の検索を、Nで取り得るすべての値(または実際にインデックスに格納されているすべてのxの値)に対して繰り返す方法が最速であると想定している場合に発生します。 +これは通常、問い合わせプランナがそのテーブルで使用可能なインデックスを考慮した時に、WHERE x = N AND y = 7700の検索を、Nで取り得るすべての値(または実際にインデックスに格納されているすべてのxの値)に対して繰り返す方法が最速であると想定している場合に発生します。 この方法は通常、xの個別値が非常に少なく、ほとんどのインデックスをスキップしてスキャンする(ほとんどのリーフページには関連するタプルが含まれないため)とプランナが期待する場合にのみ採用されます。 xの個別値が多い場合、インデックス全体のスキャンが必要になる状況になりうるため、ほとんどの場合プランナはインデックスを使用するよりもシーケンシャルスキャンを好みます。