이와 비슷한 데이터베이스 구조가 있습니다.
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 테이블의 요점은 두 개의 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'와 'ors'가 있기 때문에 SQL이 왜 '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테이블에 색인이 있습니까?