0

検索機能用のかなり大きなクエリに取り組んでいます。多数の異なる入力があり、その結果、クエリはかなり大きくなります。2 層の深さのネストされたサブクエリがある場所まで成長します。大規模なデータセットを返すものでは、パフォーマンスが問題になり、そうするために大量のレコードをふるいにかける必要がある可能性があります。比較が少ないものはうまく機能しますが、これらのいくつかはかなり悪くなっています. データベースは DB2 であり、必要なすべてのインデックスを備えているため、問題になることはありません。オプティマイザーがそれをどのように処理するのかよくわからないので、これらのクエリを実行するためにどのように書く/書き直すのが最善なのか疑問に思っています。すべてをここに書き出すことはできませんが、例を次に示します。

Select A, B 
from TableA
      --A series of joins--
WHERE TableA.A IN (
      Select C 
      from TableB
              --A few joins--
      WHERE TableB.C IN (
              Select D from TableC
              --More joins and conditionals--
              )
       )

全体に散りばめられた多くの条件もあり、その大部分は単純な等式です。あなたはアイデアを得る。サブクエリは、最初のクエリにデータを提供しません。結果をフィルタリングするためだけに存在します。私が早い段階で遭遇した問題は、最終的なクエリに組み立てられる多数の部分的なクエリ文字列を含むようにバックエンドが作成されていることです (検索オプションのために 100 以上の可能な組み合わせがあるため、クエリを作成することは単に実行不可能です)。これにより、全体的な方法が少し複雑になりました。IN の代わりに EXISTS が 1 つまたは両方のレベルで役立つかどうか、またはサブクエリの代わりに別の一連の結合が役立つかどうか、またはおそらく TableC の最初のクエリの上で WITH を使用するかどうかなどを考えています。私は間違いなくボトルネックを取り除きたいと思っています。これを処理する方法について人々が持つかもしれないフィードバック。

おそらく、両方のサブクエリ内に潜在的な結合があることも付け加えておく必要があります。

4

2 に答える 2

0

代わりに内部結合を使用すると役立つでしょう。

Select A, B
from TableA
  inner join TableB on TableA.A = TableB.C
  inner join TableC on TableB.C = TableC.D

データベースは結合用に設計されていますが、オプティマイザはサブクエリにインデックスを使用できることを理解していない可能性があります。代わりに、おそらくサブクエリを実行し、結果をメモリに保持してから、線形検索を実行して、すべてのレコードのIN演算子を評価しようとします。

ここで、必要なインデックスがすべて揃っていると言います。これについて少し考えてみてください。

1つのオプション条件がTableC.E='E'で、別のオプション条件がTableC.F ='F'の場合、両方を含むクエリには、フィールドTableC.EおよびTableC.Fのインデックスが必要になります。今日の多くの若いプログラマーは、TableC.Eに1つのインデックス、TableC.Fに1つのインデックスを持つことができると考えており、必要なのはそれだけです。実際、クエリに両方のフィールドがある場合は、両方のフィールドにインデックスが必要です。

したがって、100以上の組み合わせの場合、「必要なすべてのインデックス」には100以上のインデックスが必要になる可能性があります。

これで、TableC.E、TableC.Fのインデックスは、TableC.E条件があり、TableC.F条件がないクエリで使用できますが、TableC.F条件があり、TableC.E条件がない場合は使用できません。

何百ものインデックス?私は何をするつもりですか?

実際には、それほど悪くはありません。where句にあるかどうかに関係なくN個のオプション条件があるとしましょう。組み合わせの数は2からn番目、または数百の組み合わせの場合、Nは組み合わせの数のlog2であり、6から10の間です。また、これらのlog2条件は3つのテーブルに分散しています。一部のデータベースは複数のテーブルインデックスをサポートしていますが、DB2がサポートしているかどうかはわかりません。そのため、単一のテーブルインデックスを使用します。

つまり、私が言っているのは、TableC.EとTableC.Fの例では、次のインデックスだけでは不十分です。

TableB ON C
TableC ON D
TableC ON E
TableC ON F

一つには、オプティマイザは最後の3つのインデックスのどれを使用するかを選択する必要があります。最後の2つのインデックスにDフィールドを含めると、次のようになります。

TableB ON C
TableC ON D, E
TableC ON D, F

ここで、フィールドEもFもクエリに含まれていない場合でも、Dにインデックスを付けることができますが、どちらかがクエリに含まれている場合は、Dと他の1つのフィールドの両方にインデックスを付けることができます。

ここで、クエリに含まれる場合と含まれない場合がある10個のフィールドのインデックスがあるとします。インデックスにフィールドが1つしかないのはなぜですか?クエリに含まれる可能性の高い順に他のフィールドを追加してみませんか?

インデックスを計画するときは、それを考慮してください。

于 2013-03-12T18:36:02.427 に答える
0

「IN」述語は小さなサブクエリに適し、「EXISTS」は大きなサブクエリに適していることがわかりました。大きいものについては、「EXISTS」述語を使用してクエリを実行してみてください。

SELECT A, B 
FROM TableA
WHERE EXISTS (
      Select C 
      FROM TableB
      WHERE TableB.C = TableA.A)
于 2013-03-13T05:50:03.533 に答える