Ho una struttura di database simile a questa,
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
Lo scopo della tabella DispatchLink è collegare due record Dispatch insieme. A proposito, sto usando una chiave primaria composita sulla mia tabella di invio a causa dell'eredità, quindi non posso cambiarla senza molto dolore. Inoltre, la tabella dei collegamenti potrebbe non essere il modo corretto per farlo? Ma ancora un'eredità.
Quindi la mia domanda, se eseguo questa query
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
Non riesco mai a farlo per cercare un indice nella tabella DispatchLink. Esegue sempre una scansione dell'indice completa. Questo va bene con alcuni record, ma quando hai 50000 in quella tabella, scansiona 50000 record nell'indice secondo il piano di query. È perché ci sono 'ands' e 'ors' nella clausola join, ma non riesco a capire perché SQL non può fare un paio di ricerche sull'indice, una per il lato sinistro di 'o', e uno per il lato destro del 'o'.
Vorrei una spiegazione per questo, non un suggerimento per rendere la query più veloce a meno che ciò non possa essere fatto senza modificare la query. Il motivo è che sto usando la query sopra come filtro join di replica unione, quindi purtroppo non posso semplicemente aggiungere un altro tipo di query.
AGGIORNAMENTO: ad esempio questi sono i tipi di indici che ho aggiunto,
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)
Quindi utilizza gli indici, ma esegue una scansione dell'indice nell'intero indice, quindi 50000 record esegue la scansione di 50000 record nell'indice.




DispatchLinktavolo?