私は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
Filter1
andを含むインデックスがあるため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 を示します。Version
Account
関連するインデックスの詳細は次のとおりです。
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
このタイプのクエリがテーブルのインデックス内のすべての行をスキャンしないようにする方法はありますか?
どんな助けでも大歓迎です。