21

インデックスが一意の値を持つことがわかっている場合、そのように宣言すると、挿入または選択のパフォーマンスにどのような影響がありますか。

インデックスが一意であることをオプティマイザーが認識している場合、それはクエリ プランにどのように影響しますか?

一意性を指定することで整合性を維持できることは理解していますが、その議論はさておき、パフォーマンスへの影響はどうなるでしょうか。

4

6 に答える 6

26

簡単に言うと、データが本質的に である場合、それらにインデックスをUNIQUE作成することでメリットが得られます。UNIQIE

詳細な説明については、私のブログの記事を参照してください。


さて、悲惨な詳細。

@Mehrdadが言ったようUNIQUENESSに、プランビルダーの推定行数に影響します。

UNIQUEindex は可能な限り最大の選択性を持っています。それが理由です:

SELECT  *
FROM    table1 t2, table2 t2
WHERE   t1.id = :myid
        AND t2.unique_indexed_field = t1.value

ほぼ確実に使用しますNESTED LOOPSが、

SELECT  *
FROM    table1 t2, table2 t2
WHERE   t1.id = :myid
        AND t2.non_unique_indexed_field = t1.value

HASH JOINオプティマイザがそれnon_unique_indexed_fieldが選択的ではないと判断した場合は、a の恩恵を受ける可能性があります。

インデックスがCLUSTERED(つまり、行自体がインデックス リーフに含まれている) であり、非UNIQUE表示の場合、呼び出される特別な隠し列uniquifierが各インデックス キーに追加されるため、キーが大きくなり、インデックスが遅くなります。

そのため、UNIQUE CLUSTEREDインデックスは実際にはインデックスよりも少し効率的ですnon-UNIQUE CLUSTERED

では、呼び出された に対してOracle結合UNIQUE INDEXが必要ですkey preservation。これにより、テーブルの各行が最大 1 回選択され、ビューが更新可能になります。

このクエリ:

UPDATE  (
        SELECT  *
        FROM    mytable t1, mytable t2
        WHERE   t2.reference = t1.unique_indexed_field
        )
SET     value = other_value

で動作しますがOracle、これは次のとおりです。

UPDATE  (
        SELECT  *
        FROM    mytable t1, mytable t2
        WHERE   t2.reference = t1.non_unique_indexed_field
        )
SET     value = other_value

失敗します。

ただし、これは の問題ではありませんSQL Server

もう1つ、このようなテーブルの場合、

CREATE TABLE t_indexer (id INT NOT NULL PRIMARY KEY, uval INT NOT NULL, ival INT NOT NULL)
CREATE UNIQUE INDEX ux_indexer_ux ON t_indexer (uval)
CREATE INDEX ix_indexer_ux ON t_indexer (ival)

、このクエリ:

/* Sorts on the non-unique index first */
SELECT  TOP 1 *
FROM    t_indexer
ORDER BY
        ival, uval

を使用しますがTOP N SORT、これは次のとおりです。

/* Sorts on the unique index first */
SELECT  TOP 1 *
FROM    t_indexer
ORDER BY
        uval, ival

インデックススキャンのみを使用します。

後者のクエリの場合、は一意ivalであるため、で追加の並べ替えを行っても意味がなく、オプティマイザはこれを考慮します。uval

200,000行のサンプル データ( id == uval == ival) では、前者のクエリは15数秒間実行されますが、後者のクエリは瞬時に実行されます。

于 2009-04-16T12:07:37.640 に答える
4

もちろん、オプティマイザーは一意性を考慮します。これは、クエリ プランで予想される行数に影響します。

于 2009-04-16T10:18:42.053 に答える
1

データを挿入すると、パフォーマンスが低下します。一意性を確認する必要があります。

于 2009-04-16T10:55:16.287 に答える
1

良いテストだと思ったので、100 万行を超える Production テーブルのマシンでこれをテストしました。結果は興味深いものでした。生の数値は次のとおりです。

-- インデックスなし:

    Setup Time: 8888, Insert Time: 501690

-- 一意の制約:

    Setup Time:   42, Insert Time: 488030

セットアップは、一意の制約を追加するフィールドの最大値を取得することで構成されていたため、論理的には、制約を追加することでパフォーマンスが劇的に向上しました。これにより、この外部キーで検索するときのパフォーマンスも向上します。

興味深いことに、挿入時間もわずかに (2.7228%) 改善されたため、[私のテスト ケースでは] 制約 (+ 固有のインデックス) を追加することによるプラスの影響のみがありました。

テストでは、制約の追加によるプラスの影響のみが示され、パフォーマンスへの影響はありません。

注: 私たちのテスト システムでは、ほとんどの場合、値が一意であると予想されるため、一意でない値の挿入をテストしませんでした。このデータでは、これは本当に例外であり、パフォーマンスが必要なものではありません。

于 2014-04-15T04:53:56.630 に答える
0

はい、クエリ エンジンによって考慮されます。

于 2009-04-16T10:28:40.657 に答える
0

おそらくもっと重要なのは、一意性によってデータの整合性が保護されることです。パフォーマンスは、これを無視する理由になります。

パフォーマンスは、プラスまたはマイナスの影響を受けるか、またはまったく影響を受けない可能性があります。インデックスが使用されているかどうかなど、クエリによって異なります。

于 2009-04-16T10:28:55.147 に答える