Buna benzer bir veritabanı yapım var,
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 tablosunun amacı iki Dispatch kaydını birbirine bağlamaktır. Bu arada, miras nedeniyle gönderim masamda bileşik bir birincil anahtar kullanıyorum, bu yüzden çok fazla acı olmadan değiştiremiyorum. Ayrıca bağlantı tablosu bunu yapmanın doğru yolu olmayabilir mi? Ama yine miras.
Benim sorum, eğer bu sorguyu çalıştırırsam
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 tablosunda bir dizin araması yapmak için asla alamadım. Her zaman tam bir dizin taraması yapar. Bu, birkaç kayıtla sorun değil, ancak bu tabloda 50000 olduğunda, sorgu planına göre dizinde 50000 kaydı tarar. Birleştirme yan tümcesinde 'ands' ve 'ors' olduğu için, ancak SQL'in neden birkaç dizin araması yapamadığını, 'veya' sol tarafında bir tane, biri de 'veya' nın sağ tarafı için.
Ben bunun için bir açıklama istiyorum, sorgu ayarlama olmadan yapılabilir daha hızlı sorgu yapmak için bir öneri istiyorum. Bunun nedeni, birleştirme çoğaltma birleştirme filtresi olarak yukarıdaki sorguyu kullanıyorum, bu yüzden sadece ne yazık ki sorgu başka bir tür ekleyemezsiniz.
GÜNCELLEME: Örneğin, bunlar benim eklediğim dizin türleri,
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)
Dizinleri kullanır, ancak tüm dizin boyunca bir dizin taraması yapar, böylece 50000 kayıtlar dizinde 50000 kayıtları tarar.