4

null は DB2 でインデックス付けできないことを理解しているので、通常は日付ですが、時折 (時間の 10%) null である日付列 (sold_on) を持つ巨大なテーブル (Sales) があると仮定します。

さらに、それが変更できないレガシー アプリケーションであると仮定してみましょう。そのため、これらの null はそこにとどまり、何かを意味します (返された売上高としましょう)。

sold_on 列と total 列にインデックスを配置することで、次のクエリを高速化できます

Select * from Sales 
where 
Sales.sold_on between date1 and date2
and Sales.total = 9.99

しかし、インデックスはこのクエリを速くしません:

Select * from Sales 
where 
Sales.sold_on is null
and Sales.total = 9.99

値に対して索引付けが行われるためです。

null にインデックスを付けることはできますか? たぶん、インデックスの種類を変更することによってですか?インジケーター列にインデックスを付けますか?

4

4 に答える 4

5

DB2がNULLを索引付けしないという印象をどこから得ましたか?主張を裏付ける文書や記事には何も見つかりません。そして、NULLのごく一部を含むインデックス付き列を含むIS NULL制限を使用して、大きなテーブルでクエリを実行しました。この場合、DB2は確かに索引を使用しました(EXPLAINによって検証され、データベースが表スキャンの実行に時間を費やす代わりに即座に応答することを観察することによって)。

つまり、DB2は非主キーインデックスのNULLに問題がないと主張します。

しかし、他の人が書いているように、あなたのデータは、DB2がインデックスの使用が速くないと考える方法で構成されている可能性があります。または、関連するテーブルのデータベースの統計が最新ではありません。

于 2009-01-01T21:45:46.450 に答える
4

私は DB2 の専門家ではありませんが、値の 10% が null である場合、その列のインデックスだけではクエリに役立つとは思えません。10% はインデックスを使用するには多すぎます。テーブル スキャンを実行するだけです。2 ~ 3% について話している場合は、実際にあなたのインデックスを使用すると思います。

ページ/ブロックにあるレコードの数を考えてみてください -- たとえば 20 です。インデックスを使用する理由は、必要のないページをフェッチしないようにするためです。特定のページに null のレコードが 0 件含まれる確率は、(90%)^20、つまり 12% です。これらは良いオッズではありません。ページの 88% をフェッチする必要があるため、インデックスを使用してもあまり役に立ちません。

ただし、select 句に (* ではなく) いくつかの列しか含まれていない場合 (salesid だけと言う場合)、おそらく (sold_on,salesid) でインデックスを使用するように取得できます。必要 -- すべてのデータがインデックスに含まれます。

于 2008-09-22T16:15:50.413 に答える
1

経験則では、インデックスはレコードの 15% までの値に役立ちます。...したがって、ここではインデックスが役立つ場合があります。

DB2 が null のインデックスを作成しない場合は、ブール フィールド IsSold を追加し、sold_on の日付が設定されるたびに true に設定することをお勧めします (これはトリガーで実行できます)。

それは最も良い解決策ではありませんが、必要なものかもしれません。

于 2008-09-22T17:04:33.680 に答える
0

トロールズは正しいです。SOLD_ON 値が NULL の行でさえ、その列のインデックスの恩恵を受けます。SOLD_ON で範囲検索を行っている場合は、SOLD_ON で始まるクラスター化インデックスを作成すると、さらに多くのメリットが得られます。この特定の例では、SOLD_ON に基づいてクラスタリングの順序を維持するために追加のオーバーヘッドをそれほど必要としない場合があります。これは、追加された新しい行ほど新しい SOLD_ON 日付を持つ可能性が高いためです。

于 2009-06-17T01:53:33.270 に答える