J'ai une structure de base de données similaire à celle-ci,
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
Le point de la table DispatchLink est de lier deux enregistrements Dispatch ensemble. Soit dit en passant, j'utilise une clé primaire composite sur ma table de répartition en raison de l'héritage, donc je ne peux pas changer cela sans trop de peine. De plus, la table des liens n'est peut-être pas la bonne façon de le faire? Mais encore une fois l'héritage.
Donc ma question, si je lance cette requête
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
Je n'arrive jamais à le faire faire une recherche d'index sur la table DispatchLink. Il effectue toujours une analyse complète de l'index. C'est très bien avec quelques enregistrements, mais lorsque vous avez 50000 dans cette table, il analyse 50000 enregistrements dans l'index selon le plan de requête. C'est parce qu'il y a des «et» et des «ou» dans la clause join, mais je ne peux pas comprendre pourquoi SQL ne peut pas faire quelques recherches d'index à la place, une pour le côté gauche du «ou», et un pour le côté droit du «ou».
Je voudrais une explication à cela, pas une suggestion pour accélérer la requête, sauf si cela peut être fait sans ajuster la requête. La raison en est que j'utilise la requête ci-dessus comme filtre de jointure de réplication de fusion, donc je ne peux pas simplement ajouter un autre type de requête malheureusement.
MISE À JOUR: Par exemple, ce sont les types d'index que j'ai ajoutés,
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)
Il utilise donc les index, mais effectue une analyse d'index sur l'ensemble de l'index, donc 50000 enregistrements, il analyse 50000 enregistrements dans l'index.
DispatchLink
table?