0

クエリは巨大なテーブルで実行されます (10 億レコード以上)

identcol > (ParamTable から bigint(identval) を選択) である TableA から Col1 を選択します。

( identvaldatatype is character and identcolis BIGINT) これには長い時間がかかり、完全なテーブル スキャンが実行されます。サブクエリを置き換えて、identcol の where 句で数値を使用すると、その列のインデックスが使用され始めます。

リテラル値を指定せずに DB2 にこのインデックスを強制的に使用させる方法はありますか? (AIX 上の DB2 9.7 luw)

編集: BETWEEN がサブクエリと上限値で機能し、インデックスも使用していることがわかりました。また、BIGINT への明示的なキャストを削除すると、インデックスの使用が開始されます。しかし、それでも技術的な説明/ポインターを知りたいです。ありがとう!

4

1 に答える 1

2

この動作は、リテラル値がない場合にクエリ オプティマイザーが利用できる情報が不十分であることが原因である可能性があります。

述部にリテラル値が指定されている場合、オプティマイザは値の分散統計を使用してtableA.identcol、条件に一致する行数を推定できます。どうやら、配布は、提供されたリテラル値が与えられると、インデックスベースのアクセスをより適切に考慮するようなものです。

代わりにサブクエリを指定すると、オプティマイザは何identvalが返されるかを知る方法がないため、推測を行いますが、あなたの場合は最適ではないことがわかります。

より一貫した最適化結果を得るには、オプティマイザに追加情報を提供する必要があります。いくつかのオプションを試すことができます。

  1. 次のような統計ビューを作成しますcreate view sv1 as select Col1 from TableA, ParamTable where TableA.identcol > ParamTable.identval(クエリから を削除bigint()します。オプティマイザをさらに混乱させる必要はありません)。次に、統計ビューの最適化を有効にし ( alter view sv1 enable query optimization)、配布統計を収集する必要があります ( runstats on table sv1 with distribution)。ただし、ParamTable行が 1 つしかないため、頻繁に変更されると思われるので、変更のたびに統計が更新されるようにする必要がありますParamTable.identval
  2. 明示的な選択性の見積もりをオプティマイザーに提供します: Select Col1 from TableA where identcol > (select bigint(identval) from ParamTable) selectivity 0.001。その前に、この動作を有効にする DB2 レジストリー変数を設定し ( db2set DB2_SELECTIVITY=ALL)、インスタンスを再始動する必要があります。0.001は、条件を満たすテーブルの割合 (この場合は 0.1%) を示します。0.001一致する行の割合の現実的な見積もりに置き換えます。

  3. TableA (identcol, Col1)インデックスがまだ存在しない場合は作成します(そしてその統計を収集します)。これにより、インデックスのみのアクセスが可能になる場合があります。

于 2015-09-10T01:14:50.283 に答える