使用CTE或临时表时SQL Server查询速度慢

时间:2012-10-10 16:01:33

标签: sql-server

我有一个SQL查询,它会记录日期并报告过去7天内已扫描到软件仓库中的托盘数量,但不会在给定日期之前扫描出来。运行大约需要一秒钟。我需要在过去14天内报告此号码(使用SSRS报告)。但是 - 当我创建CTE或临时表来生成要报告的日期时,而不是上升到10秒(大约10个日期),它会上升到超过3分钟!

请告知。

以下是单日期报告:

DECLARE @back integer
SET @back = 7
Declare @testDate DateTime
SET @testDate = '2012-10-09'
--opening balance query
select count(p.PalletID) as Opening_Balance
FROM [POSTALE].[dbo].[Pallet] p
join [POSTALE].[dbo].[Tracking] t on t.PalletID = p.PalletID
--scan was before indicated day
where CAST(DateAdd(hour, -6, t.TrackDateTime) as DATE) <= @testDate
--scan was after number of days to look back
and CAST(DateAdd(hour, -6, t.TrackDateTime) as DATE) >= dateadd(day, 0 - @back, @testDate)
--scanned into hub (get only the earliest occurence)
and t.TrackingID = (select top 1 tr.TrackingID from [POSTALE].[dbo].[Tracking] tr 
                where tr.TrackCode in ('SCAN OFF TRUNK HUB', 'DAYS') 
                and tr.PalletID = t.PalletID order by tr.TrackingID)
--not scanned out of hub by the indicated day
and (select count(tr.TrackingID) from [POSTALE].[dbo].[Tracking] tr where t.PalletID = tr.PalletID and 
    CAST(DateAdd(hour, -6, tr.TrackDateTime) as DATE) <= @testDate and tr.TrackCode in 
    ('SCAN ONTO TRUNK DEPOT', 'SCAN OFF TRUNK DEPOT', 'SECURITY SCAN AT DEPOT', 'SCAN OFF TRUNK DEPOT', 'SCANNER BROKEN',
    'SCAN ON DEPOT VEHICLE', 'POD ADDED','NO POD ADDED')) = 0

以下是将其加入CTE的代码:

DECLARE @back integer
SET @back = 7
declare @start_date as date;
set @start_date = cast(getdate() - 14 as date);
declare @end_date as date;
set @end_date = cast(getdate() as date);
WITH DateList AS
(
    SELECT @start_date AS start_date
    UNION ALL
    SELECT DATEADD(DAY, 1, start_date)
    FROM DateList
    WHERE DATEADD(DAY, 1, start_date) < @end_date
)
SELECT
    (select count(p.PalletID) as Opening_Balance
...
,datediff(DAY, d.start_date, getdate()) as daysBack
from DateList d
order by d.start_date

..这里是临时表版本:

DECLARE @back integer
SET @back = 7
--hours into day that get pushed back to previous day
DECLARE @dayStart integer
set @dayStart = 12
--today + 12 hours as datetime
Declare @date12 as datetime
set @date12 = DateAdd(hour, @dayStart, cast(cast(getdate() as date) as datetime))
--temporary table to create list of dates to report on
DECLARE @DateList TABLE(
        DayDate DateTime
)
insert into @DateList (DayDate) Select DateAdd(day, - 14, @date12) where datepart(weekday, getdate() - 14) <> 7 and datepart(weekday, getdate() - 14) <> 1
insert into @DateList (DayDate) Select DateAdd(day, - 13, @date12) where datepart(weekday, getdate() - 13) <> 7 and datepart(weekday, getdate() - 13) <> 1
insert into @DateList (DayDate) Select DateAdd(day, - 12, @date12) where datepart(weekday, getdate() - 12) <> 7 and datepart(weekday, getdate() - 12) <> 1
insert into @DateList (DayDate) Select DateAdd(day, - 11, @date12) where datepart(weekday, getdate() - 11) <> 7 and datepart(weekday, getdate() - 11) <> 1
insert into @DateList (DayDate) Select DateAdd(day, - 10, @date12) where datepart(weekday, getdate() - 10) <> 7 and datepart(weekday, getdate() - 10) <> 1
insert into @DateList (DayDate) Select DateAdd(day, - 9, @date12) where datepart(weekday, getdate() - 9) <> 7 and datepart(weekday, getdate() - 9) <> 1
insert into @DateList (DayDate) Select DateAdd(day, - 8, @date12) where datepart(weekday, getdate() - 8) <> 7 and datepart(weekday, getdate() - 8) <> 1
insert into @DateList (DayDate) Select DateAdd(day, - 7, @date12) where datepart(weekday, getdate() - 7) <> 7 and datepart(weekday, getdate() - 7) <> 1
insert into @DateList (DayDate) Select DateAdd(day, - 6, @date12) where datepart(weekday, getdate() - 6) <> 7 and datepart(weekday, getdate() - 6) <> 1
insert into @DateList (DayDate) Select DateAdd(day, - 5, @date12) where datepart(weekday, getdate() - 5) <> 7 and datepart(weekday, getdate() - 5) <> 1
insert into @DateList (DayDate) Select DateAdd(day, - 4, @date12) where datepart(weekday, getdate() - 4) <> 7 and datepart(weekday, getdate() - 4) <> 1
insert into @DateList (DayDate) Select DateAdd(day, - 3, @date12) where datepart(weekday, getdate() - 3) <> 7 and datepart(weekday, getdate() - 3) <> 1
insert into @DateList (DayDate) Select DateAdd(day, - 2, @date12) where datepart(weekday, getdate() - 2) <> 7 and datepart(weekday, getdate() - 2) <> 1
insert into @DateList (DayDate) Select DateAdd(day, - 1, @date12) where datepart(weekday, getdate() - 1) <> 7 and datepart(weekday, getdate() - 1) <> 1
SELECT
    (select count(p.PalletID) as Opening_Balance
...
,datediff(DAY, d.DayDate, getdate()) as daysBack
from @DateList d
order by d.DayDate

1 个答案:

答案 0 :(得分:2)

你没有描述你的索引,这显然是一个很大的因素,但有一件事我注意到你的WHERE子句的元素不是sargable而且可能是。

例如,尝试更改:

where CAST(DateAdd(hour, -6, t.TrackDateTime) as DATE) <= @testDate 

where t.TrackDateTime < dateadd(hour, 6, dateadd(day, 1, @testDate))

你需要对这一行做类似的事情:

and CAST(DateAdd(hour, -6, t.TrackDateTime) as DATE) >= dateadd(day, 0 - @back, @testDate)