私はこれに似たデータベース構造を持っています、
CREATE TABLE [dbo].[Dispatch](
[DispatchId] [int] NOT NULL,
[ContractId] [int] NOT NULL,
[DispatchDescription] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_Dispatch] PRIMARY KEY CLUSTERED
(
[DispatchId] ASC,
[ContractId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[DispatchLink](
[ContractLink1] [int] NOT NULL,
[DispatchLink1] [int] NOT NULL,
[ContractLink2] [int] NOT NULL,
[DispatchLink2] [int] NOT NULL
) ON [PRIMARY]
GO
INSERT [dbo].[Dispatch] ([DispatchId], [ContractId], [DispatchDescription]) VALUES (1, 1, N'Test')
GO
INSERT [dbo].[Dispatch] ([DispatchId], [ContractId], [DispatchDescription]) VALUES (2, 1, N'Test')
GO
INSERT [dbo].[Dispatch] ([DispatchId], [ContractId], [DispatchDescription]) VALUES (3, 1, N'Test')
GO
INSERT [dbo].[Dispatch] ([DispatchId], [ContractId], [DispatchDescription]) VALUES (4, 1, N'Test')
GO
INSERT [dbo].[DispatchLink] ([ContractLink1], [DispatchLink1], [ContractLink2], [DispatchLink2]) VALUES (1, 1, 1, 2)
GO
INSERT [dbo].[DispatchLink] ([ContractLink1], [DispatchLink1], [ContractLink2], [DispatchLink2]) VALUES (1, 1, 1, 3)
GO
INSERT [dbo].[DispatchLink] ([ContractLink1], [DispatchLink1], [ContractLink2], [DispatchLink2]) VALUES (1, 3, 1, 2)
GO
DispatchLinkテーブルのポイントは、2つのDispatchレコードをリンクすることです。ちなみに、レガシーのためにディスパッチテーブルで複合主キーを使用しているので、多くの苦労なしにそれを変更することはできません。また、リンクテーブルはそれを行う正しい方法ではないかもしれませんか?しかし、再びレガシー。
だから私の質問、このクエリを実行すると
select * from Dispatch d
inner join DispatchLink dl on d.DispatchId = dl.DispatchLink1 and d.ContractId = dl.ContractLink1
or d.DispatchId = dl.DispatchLink2 and d.ContractId = dl.ContractLink2
DispatchLinkテーブルでインデックスシークを実行することはできません。常にフルインデックススキャンを実行します。少数のレコードで問題ありませんが、そのテーブルに50000がある場合、クエリプランに従ってインデックス内の50000レコードをスキャンします。これは、結合句に「ands」と「or」が含まれているためですが、SQLが代わりに2つのインデックスシークを実行できない理由を頭で理解できません。1つは「or」の左側です。 1つは「or」の右側にあります。
これについての説明をお願いします。クエリを調整せずに実行できない限り、クエリを高速化するための提案ではありません。その理由は、上記のクエリをマージレプリケーション結合フィルターとして使用しているため、残念ながら別の種類のクエリを追加することはできないためです。
更新:たとえば、これらは私が追加しているインデックスのタイプです、
CREATE NONCLUSTERED INDEX IDX1 ON DispatchLink (ContractLink1, DispatchLink1)
CREATE NONCLUSTERED INDEX IDX2 ON DispatchLink (ContractLink2, DispatchLink2)
CREATE NONCLUSTERED INDEX IDX3 ON DispatchLink (ContractLink1, DispatchLink1, ContractLink2, DispatchLink2)
したがって、インデックスを使用しますが、インデックス全体でインデックススキャンを実行するため、50000レコードはインデックス内の50000レコードをスキャンします。
DispatchLink
テーブルにインデックスはありますか?