web-dev-qa-db-ja.com

グループ化フィールドのインデックスを作成しますか?

Oracleデータベースのgroup byフィールドのフィールドにインデックスを作成する必要がありますか?

例えば:

select * 
from some_table
where field_one is not null and field_two = ?
group by field_three, field_four, field_five

私は上記のために作成したインデックスをテストしており、このクエリに関連する唯一のインデックスは、field_twoに対して作成されたインデックスです。他のフィールドで作成された他の単一フィールドまたは複合インデックスは、上記のクエリには使用されません。この音は正しいですか?

27
onejigtwojig

それは正しいかもしれませんが、それはあなたが持っているデータの量に依存します。通常、私はGROUP BYで使用していた列のインデックスを作成しますが、オプティマイザは、field_twoインデックスを使用した後、GROUPの他のインデックスを使用して正当化するのに十分なデータが返されないと判断した可能性があります沿って。

14
Eric Petroelje

いいえ、これは正しくない可能性があります。

大きなテーブルがある場合、Oracleは、すべての値をカバーする単一のインデックスがない場合でも、テーブルからではなくインデックスからフィールドを派生することを優先できます。

私のブログの最新の記事では:

Oracleが全表スキャンを使用せず、2つのインデックスを結合して列の値を取得するクエリがあります。

SELECT  l.id, l.value
FROM    t_left l
WHERE   NOT EXISTS
        (
        SELECT  value
        FROM    t_right r
        WHERE   r.value = l.value
        )

計画は次のとおりです。

SELECT STATEMENT
 HASH JOIN ANTI
  VIEW , 20090917_anti.index$_join$_001
   HASH JOIN
    INDEX FAST FULL SCAN, 20090917_anti.PK_LEFT_ID
    INDEX FAST FULL SCAN, 20090917_anti.IX_LEFT_VALUE
  INDEX FAST FULL SCAN, 20090917_anti.IX_RIGHT_VALUE

ご覧のとおり、ここにはTABLE SCANt_leftはありません。

代わりに、Oracleidvalueのインデックスを取得し、それらをrowidで結合し、結合結果から(id, value)ペアを取得します。

今、あなたのクエリに:

SELECT  *
FROM    some_table
WHERE   field_one is not null and field_two = ?
GROUP BY
        field_three, field_four, field_five

まず、*句を含むテーブルからGROUP BYを選択しているため、コンパイルされません。

*を、グループ化列と非グループ化列の集計に基づく式に置き換える必要があります。

次のインデックスが役立つでしょう。

CREATE INDEX ix_sometable_23451 ON some_table (field_two, field_three, field_four, field_five, field_one)

、これにはfield_twoでのフィルタリング、field_three, field_four, field_fiveでの並べ替え(GROUP BYに便利)、およびfield_oneNOT NULLであることの確認の両方のすべてが含まれるため。

9
Quassnoi

Oracleデータベースのgroup byフィールドのフィールドにインデックスを作成する必要がありますか?

いいえ。インデックスが存在するかどうかに関係なくクエリを実行するという意味では、その必要はありません。インデックスは、クエリのパフォーマンスを向上させるために提供されています。

ただし、それは役立ちます。ただし、データベースへの新しいインデックスの影響の可能性を考慮せずに、1つのクエリを支援するためだけにインデックスを追加することをためらっています。

...このクエリに関連する唯一のインデックスは、field_twoに対して作成されたインデックスです。他のフィールドで作成された他の単一フィールドまたは複合インデックスは、上記のクエリには使用されません。この音は正しいですか?

常にではない。多くの場合、GROUP BYはOracleにソートの実行を要求します(常にではありません)。ソートする列に適切なインデックスを提供することで、ソート操作を排除できます。

ただし、実際にGROUP BYのパフォーマンスについて心配する必要があるかどうかは、考慮する必要がある重要な質問です。

2
Jeffrey Kemp