2009-12-08 29 views
8

私はテーブル複数の列のインデックス - 1つの列に対してのみクエリを実行するとOKですか?

create table sv (id integer, data text) 

とインデックスがある場合:私は、クエリ

select * from sv where id = 10 
をしなかった場合

create index myindex_idx on sv (id,text) 

が、これはやはり便利だろうが

尋ねるための私の理由は、私は「ということですインデックスを持たないテーブルのセットを調べ、選択されたクエリのさまざまな組み合わせを見ることができます。 1つの列だけを使用するものもあれば、複数の列を持つものもあります。両方のセットでインデックスを取得する必要があるのですか、それともすべてを含むインデックスですか? フルテーブルスキャンより高​​速なルックアップのためにインデックスを追加しています。

(マット・ハギンズによって回答に基づいて)例:

select * from table where col1 = 10 
select * from table where col1 = 10 and col2=12 
select * from table where col1 = 10 and col2=12 and col3 = 16 

は、すべてのインデックステーブルでカバーすることができた(co1l1、COL2、COL3)が、

select * from table where col2=12 

は別のインデックスが必要でしょうか?

+0

私は<3 StackOverflowです。優れた答えは、予想以上に良い方法です。私が使用した答えを受け入れ、最高の投票回答を受け入れられた回答の下の補足にする – svrist

答えて

15

(id、text)のインデックスは、最初にid、次にテキストでインデックス付けするので便利です。

  • idでクエリすると、このインデックスが使用されます。
  • id &テキストでクエリすると、このインデックスが使用されます。
  • テキストでクエリすると、このインデックスは使用されません。

編集:私はそれが「役に立つ」と言うとき、私はそれがクエリの速度/最適化の点では便利ですを意味します。 Sune Rievers氏が指摘したように、IDを指定した独自のレコードを取得するわけではありません(IDをテーブル定義で一意に指定しない限り)。

+2

「テキスト」でクエリを実行すると、コスト見積もりがインデックススキップスキャン、インデックススキャン、または高速フルインデックススキャンに有利な場合があります。 –

2

idが主キーであると仮定します。インデックスにはプライマリキーが追加されることはありません。常にプライマリキーになります。他のものにユニークなものを追加することもユニークになります。

本当に必要な場合はtextにユニークなインデックスを追加します。それ以外の場合はidをテーブルの一意性として使用してください。

idがプライマリキーでない場合、クエリから一意の結果を得ることは保証されません。

col2で検索した最後の例については、別のインデックスが必要な場合があります。索引はパフォーマンスの問題を解決するすべての解決策ではありませんが、データベース設計や問合せを最適化する必要がある場合があります。たとえば、ストアド・プロシージャに書き直す必要があります(Oracleには完全にはわかりませんが、同等)。

+1

PKインデックスに別の列を追加すると、かなりの数のクエリでインデックスのみを使用してテーブルアクセスは完全に。 –

+0

Trueですが、他の(基本キー)列にインデックスを追加する場合も同様です。単一値キー+別のインデックスよりも複合キーのパフォーマンスが少し向上する可能性があります。 –

8

Oracleは、インデックスを使用してのいくつかの方法をサポートしており、あなたがそれらのすべてを理解することから始めるべきですので、ここで迅速な読み取りを持っている:大手場合http://download.oracle.com/docs/cd/B19306_01/server.102/b14211/optimops.htm#sthref973

あなたのクエリselect * from table where col2=12は有効インデックススキップスキャンを活用することができ列のカーディナリティーが非常に低くなっているか、高速でない場合は完全なインデックススキャンになります。これらはおそらくレポートの実行には問題ありませんが、OLTPクエリの場合は、col2を先頭にしてインデックスを作成する方がよいでしょう。

+1

+1インデックススキップスキャンに言及します。索引圧縮、データ・カーディナリティ、統計、すべてが一緒に使用して計画を定義します。 – ewernli

2

質問の背後にあるドライバは、複数の列を持つテーブルがあり、これらの列の任意の組み合わせをクエリで使用できる場合、BITMAPインデックスを参照する必要があります。

あなたの例を見て:あなたは3ビットマップ索引作成することができ

select * from mytable where col1 = 10 and col2=12 and col3 = 16 

create bitmap index ix_mytable_col1 on mytable(col1); 
create bitmap index ix_mytable_col2 on mytable(col2); 
create bitmap index ix_mytable_col3 on mytable(col3); 

をこれらのビットマップ索引は、必要に応じて、彼らがを組み合わせることができるという大きな利点を持っています。

ので、次のクエリのそれぞれは、インデックスの一つ以上を使用します。

select * from mytable where col1 = 10; 

select * from mytable where col2 = 10 and col3 = 16; 

select * from mytable where col3 = 16; 

ので、ビットマップ索引は、あなたのための選択肢かもしれません。しかし、David Aldridge氏は、特定のデータセットに応じて、(col1、col2、col3)の単一のインデックスが望ましいかもしれないと指摘しています。これまでどおり、それは依存します。あなたのデータとそのデータに対する疑わしいクエリを見て、あなたの統計が最新であることを確認してください。

これが役に立ちます。

+0

+1非常に面白いです。ビットマップ配列は分かっていませんでしたが、http://en.wikipedia.org/wiki/Bitmap_indexには素敵な短い記事があります。 –

+1

ビットマップ索引は、同時変更には親切ではないので、通常、OLTPシステムではあまり選択肢にはなりません。 –

+0

真。 OLTPで貧弱 - データウェアハウスで素晴らしい。 "これまでどおり、それは依存する"。 –

関連する問題