2009-03-18 6 views
1

良い日、複数のビット列にインデックスを作成するためのベストプラクティスは何ですか?

SQL Server 2005では、いくつかのブール型(ビット)列を含む多数の列があります。たとえば、 テーブル 'Person'には列IDと列HasItem1、HasItem2、HasItem3、HasItem4があります。この表はちょっと大きいので、より速い検索結果を得るために索引を作成したいと考えています。

ビット列にインデックスを作成するのは良い考えではないことがわかっています。そのため、すべてのビット列でインデックスを使用することを考えました。しかし、問題は、これらのビット列のすべてがクエリ内にあるかどうかではないことです。索引付けされた列の順序は索引で重要であり、どの索引付け列が問合せで使用されるかわからないので、これをどのように処理する必要がありますか?

ところで、既に削除できないインデックスがクラスタ化されています。

答えて

0

偶然SQLがperson_idとitem_idとBitValueを持つ大規模なテーブルを照会するのは簡単でしょうが、Item1、Item2、...という単一のテーブルを検索することになります。N

2

これはおそらく良い考えではないと思います。カーディナリティが非常に低いフィールドのインデックスを作成しようとすると、通常はクエリが高速化されず、インデックスを維持するオーバーヘッドが発生します。

通常、ビットフィールドの1つを別のフィールドで検索する場合、2つのフィールドの複合インデックスが役に立ちます。

ビットフィールドにコンポジットインデックスを作成する場合は、インデックスの先頭のコンポジットフィールドが指定されている場合にのみ役立ちます。コンポジットインデックス内に最初の値を含めない場合、インデックスはまったく使用されません。

例としてbitaがクエリの90%で使用され、70%でbitd、bとcが20%で使用された場合、(bita、bitd、bitb、bitc)の複合インデックスは、クエリの少なくとも10%、場合によっては40%でもインデックスはほとんど使用されないでしょう。

おそらく、同じデータ量とデータのカーディナリティで試してみて、実行計画が何を示しているのかを知ることをお勧めします。

2

SQL Serverの詳細はよくわかりませんが、一般的に一意でないデータを持つ列のインデックス作成はあまり効果的ではありません。一部のRDBMSシステムでは、オプティマイザは特定のパーセント以下のインデックスを無視するため、インデックスは存在しない場合もあります。

コンポジットまたはマルチカラムインデックスを使用すると、フィルタ制約がインデックスと同じ順序である場合にのみ役立ちますが、インデックスに 'field1、field2'が含まれていて検索している'field2、field1'またはその他の組み合わせの場合、インデックスは使用できません。最適化したい特定の検索ケースごとにインデックスを追加することができます。これはあなたができると考えることができるすべてのものです。また、ビットフィールドのすべてを考慮してもデータがあまりユニークではない場合でも、インデックスは無視されます。

たとえば、3ビットのフィールドがある場合、データを8つの異なるグループに分けるだけです。テーブルに適切な数の行がある場合、8でセグメント化することはあまり効果的ではありません。

0

2005年についてはわかりませんが、SQL Server 2000(Books Onlineから): "タイプビットの列にインデックスを付けることはできません。

0

チェックサムの使用はどうですか?

は今、あなたはビットの組み合わせを表す値を持っているあなたのテーブルにmysumという名前のint型のフィールドを追加し、この

UPDATE checksumtest SET mysum = CHECKSUM(hasitem1,hasitem2,hasitem3,hasitem4) 

を実行します。

検索クエリで同じチェックサムを計算し、mysumで一致させます。

これにより処理が速くなる可能性があります。

+0

ビットフィールドでチェックサムを実行することには、インデックス付けに同じ制限があります。 4つのビットフィールドをチェックサムすることによって生成される16のユニークな値しか持たないので、一意性は低くなります。 – dnewcome

+0

確かに、あなたは1つのフィールドだけを検索していますよね? – Sam

0

データベースの設計を見直す必要があります。フィールドHasItem1〜HasItem#を持つテーブルを持つ代わりに、ブリッジエンティティを作成し、マスターItemsテーブルがない場合は作成する必要があります。ブリッジエンティティ(テーブル)person_itemsには、最低でも2つのフィールドがあります。person_id and item_ id。

この方法でデータベースを設計しても、を処理するデータベースにはロックされません。N列定義に基づいた項目数。マスターアイテムテーブルに必要な数だけアイテムを追加し、必要なだけ多くの人を必要な数だけ関連付けることができます。

関連する問題