Tengo una estructura de base de datos similar a esta,
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
El objetivo de la tabla DispatchLink es vincular dos registros de envío juntos. Por cierto, estoy usando una clave primaria compuesta en mi tabla de despacho debido al legado, por lo que no puedo cambiar eso sin mucho dolor. Además, la tabla de enlaces puede no ser la forma correcta de hacerlo Pero de nuevo legado.
Entonces mi pregunta, si ejecuto esta consulta
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
Nunca puedo conseguir que haga una búsqueda de índice en la tabla DispatchLink. Siempre hace un escaneo de índice completo. Eso está bien con algunos registros, pero cuando tiene 50000 en esa tabla, escanea 50000 registros en el índice de acuerdo con el plan de consulta. Es porque hay 'ands' y 'ors' en la cláusula de unión, pero no puedo entender por qué SQL no puede hacer un par de búsquedas de índice, una para el lado izquierdo de 'o', y uno para el lado derecho de 'o'.
Me gustaría una explicación para esto, no una sugerencia para hacer que la consulta sea más rápida a menos que se pueda hacer sin ajustar la consulta. La razón es que estoy usando la consulta anterior como un filtro de combinación de replicación de combinación, por lo que desafortunadamente no puedo agregar otro tipo de consulta.
ACTUALIZACIÓN: Por ejemplo, estos son los tipos de índices que he estado agregando,
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)
Por lo tanto, utiliza los índices, pero realiza un escaneo del índice en todo el índice, por lo que 50000 registros escanea 50000 registros en el índice.
DispatchLink
mesa?