4

私は2つのテーブルを持っています

Account:
    AccountUID bigint (Primary Key)
    AccountID bigint
    Version smallint
    CustomerName varchar(50)

注: AccountID と CurrentVersion も一意のキーの一部です。

AccountStatus:
    AccountID bigint (Primary Key)
    CurrentVersion smallint
    Filter1 varchar(10)
    Filter2 varchar(10))

AccountID簡単にするために、現在、それぞれに 1 つのバージョンしかないため、それぞれに 100 行あります。Filter1およびテーブルに値がFilter2あり、次の操作を行うと 10 レコードが返されます。

SELECT *
FROM AccountStatus acs
WHERE acs.Filter1=SomeValue1 and acs.Filter2=SomeValue2

Filter1andを含むインデックスがあるためFilter2、実際の実行計画では、実際の行の値に選択された 10 行のみを含むインデックス シークが表示されます。

次のようにテーブルに参加するとAccount、同じ 10 個のレコードが得られます。

SELECT acs.*
FROM AccountStatus acs
    INNER JOIN Account a ON acs.AccountID=a.AccountID
                            AND acs.CurrentVersion=a.Version
WHERE acs.Filter1=SomeValue1 and acs.Filter2=SomeValue2

ただし、実際の実行計画を見ると、AccountStatus以前と同じようにテーブルに 10 個の実際の行があるインデックス シークが表示されます。ただし、その上に、テーブルのAccountID andを含むインデックスのインデックス スキャンが表示されます。また、この「アクション」は、Actual Rows で 100 を示します。VersionAccount

関連するインデックスの詳細は次のとおりです。

CREATE NONCLUSTERED INDEX [IX_Find] ON [dbo].[AccountStatus] 
(
    [Filter1] ASC,
    [Filter2] ASC
)
INCLUDE ( [AccountID],
[CurrentVersion]
) WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]

CREATE UNIQUE NONCLUSTERED INDEX [IX_Account_Status] ON [dbo].[Account] 
(
    [AccountID] ASC,
    [Version] ASC
)
INCLUDE ( [AccountUID]) WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]

これは 100 行ではそれほど大きなパフォーマンス ヒットではありませんが、100 万行または数百万行になると、より心配になります。これは非常に非効率になります。

Accountこのタイプのクエリがテーブルのインデックス内のすべての行をスキャンしないようにする方法はありますか?

どんな助けでも大歓迎です。

4

2 に答える 2

1

実行計画は、テーブルとそのインデックス付き列の統計に基づいています。100 行しかない場合、10m 行の場合とは異なる実行計画になります。インデックスを使用しないことが心配な場合は、実行計画を再度確認する前に、データの量を増やして統計を更新する必要があります。エンジンは非常にスマートで、多くの場合、実行計画の最速バージョンを選択します。

フィルター 1 はかなりの量の行に一致すると想定していますが、エンジンがこの数行のシークでスキャンを実行するのにそれほど時間がかからないため、エンジンはスキャンを使用するだけです。

于 2014-04-30T21:19:42.377 に答える
0

インデックスが必要かどうかを判断する方法は、2 つの方法のいずれかです。1 つ目は、推定実行計画の表示を使用してクエリを実行することです。次に、実行計画でインデックスが見つからないことが示されている場合 (緑色)、緑色の見つからないインデックス メッセージを右クリックし、[Missing Index Details...] を選択します。これにより、このクエリに役立つ不足しているインデックスを挿入するコードを含む新しいウィンドウが開きます。コードの下部セクションのコメントを外し、新しいインデックスの名前に置き換えて、コードを実行するだけです。

このコードに役立つインデックスが見つからない場合は、このプロセスを数回繰り返す必要がある場合があります。

2 番目の方法は、データベースのパフォーマンスに対する長期的なアプローチです。

PINAL DAVE は、自身のブログ ( http://blog.sqlauthority.com/ ) で一連のスクリプトを公開しています。これらのスクリプトは、欠落しているインデックスや未使用の重複インデックスを識別するのに役立ちます。これらを定期的に実行して、どのインデックスが役に立ち、実際にパフォーマンスを低下させているかを判断します。

不足しているインデックスを追加し、未使用または重複するインデックスを削除します。

于 2013-08-29T18:55:38.547 に答える