INSERT INTO [dbo].[Product] VALUES (1); INSERT INTO [dbo].[Product] VALUES (2); INSERT INTO [dbo].[Product] VALUES (3); INSERT INTO [dbo].[Product] VALUES (4); INSERT INTO [dbo].[Product] VALUES (5); INSERT INTO [dbo].[Product] VALUES (6); INSERT INTO [dbo].[Product] VALUES (7); INSERT INTO [dbo].[Product] VALUES (8); INSERT INTO [dbo].[Product] VALUES (9); INSERT INTO [dbo].[Product] VALUES (10);
SELECT p.* FROM dbo.T99 t JOIN [dbo].[ReportPeriod] p ON t.CreateDate BETWEEN p.StartDate AND p.EndDate JOIN@Transaction t1 ON t.TransactionId = t1.TransactionId AND p.ProductId = t1.ProductId
CREATE CLUSTERED INDEX [CIX_ReportPeriod_StartDate] ON [dbo].[ReportPeriod] ( [StartDate] ASC, [EndDate] ASC )
原因出在範圍條件會因為查找範圍過大導致預估值不準確
甚麼意思? 讓我們看看下圖(代表ReportPeriod內含日期資料)
而我們在JOIN條件只有t.CreateDate BETWEEN p.StartDate AND p.EndDate這就會導致,我們需要查找ReportPeriod日期資料在挑出符合的資料
1 2
JOIN [dbo].[ReportPeriod] p ON t.CreateDate BETWEEN p.StartDate AND p.EndDate JOIN@Transaction t1 ON t.TransactionId = t1.TransactionId AND p.ProductId = t1.ProductId
ALTER TABLE dbo.T99 ADD PeriodDate AS DATEADD(MINUTE,DATEPART(MINUTE,CreateDate) %5*-1, DATETIMEFROMPARTS( DATEPART(YEAR,CreateDate), DATEPART(MONTH,CreateDate), DATEPART(DAY,CreateDate), DATEPART(HOUR,CreateDate), DATEPART(MINUTE,CreateDate),0,0) )
建立完新COLUMN後別忘記加入一個Index給此COLUMN.
1 2 3
CREATE INDEX IX_PeriodDate_T99 ON dbo.T99( PeriodDate )
最後我們修改一下查詢語法
1 2 3 4
SELECT p.* FROM dbo.T99 t JOIN [dbo].[ReportPeriod] p ON p.StartDate = t.PeriodDate JOIN@Transaction t1 ON t.TransactionId = t1.TransactionId AND p.ProductId = t1.ProductId