我有一个脚本,在给定的时间段内只返回有问题的行,并复制超过60秒发送的任何行。这可以通过以下连接来实现:
FROM Table t
INNER JOIN CTE_DayHourMinutes dhm ON
Calculate_Date >= t.[Start Date]
AND
dhm.Calculate_Date <= t.[End Date]
对于表t中的每个记录,它与计算日期的YYYY-MM-DD HH-MM-SS匹配在一起。唯一的问题是返回100条记录需要10分钟左右。最终,该脚本应在一个系统内部使用,该系统可能有数千甚至数百万行,因为我们希望能够获得三个月的数据。
我还应该提一下,我已经测试了脚本的其余部分,并且每个工作正常并且在运行必要的CTE和其他部分时没有性能问题。唯一的问题是我尝试进行上述连接的方式以及它必须检查的行数,目前这需要太长时间。
因此,我不知道如何以类似的方式实现上述目标,但提高了脚本的性能。
DECLARE
@startDate DateTime
, @currentDate DateTime
/* Demo System */ SET @currentDate = '2014-04-26'
SET @startDate = DATEADD(day, -10 , @CurrentDate)
-- Create a list of Days (depending on the month in question)
-------------------------------------------------------------
; WITH CTE_dayList as
(
SELECT @startDate as cal_day
union all
SELECT DATEADD(DAY , 1, d1var.cal_day) as cal_day FROM CTE_daylist d1var
WHERE DATEADD(DAY , 1, d1var.cal_day) <= @currentDate
)
-- Create a list of hours 0 - 23 (24 hours)
-------------------------------------------
, CTE_hourList as
(
SELECT 0 as cal_hour
union all
SELECT h1var.cal_hour + 1 as cal_hour FROM CTE_hourList h1var
WHERE h1var.cal_hour + 1 <= 23
)
-- Create a list of minutes 0 - 59 (1 hour)
-------------------------------------------
, CTE_minuteList as
(
SELECT 0 as cal_minute
union all
SELECT m1var.cal_minute + 1 as cal_minute FROM CTE_minuteList m1var
WHERE m1var.cal_minute + 1 <= 59
)
-- Create a day , hour and minnute -- cross join the hour and minute onto each day between the two dates.
, CTE_DayHourMinutes as
(
SELECT
-- cast the cal_day (date) with the hours and minute, to create a date and time.
CAST(CAST(cal_day AS VARCHAR) + CAST(CAST(cal_hour as VARCHAR) + ':' + CAST(cal_minute AS VARCHAR) AS DATETIME) AS DATETIME) AS Calculate_Date
FROM CTE_dayList
CROSS JOIN
(SELECT cal_hour , cal_minute FROM CTE_hourList CROSS JOIN CTE_minuteList) DHMList)
-- create transmission end date and time ( required for the join in the main select statement )
, CTE_Text RF as
(
SELECT
H.ObjectGuid AS Transmission_ID
, CAST(H.[TRDateTime] AS DateTime) AS [Transmission Start Date]
, CAST(DATEADD(second, HT.ElapsedTime, H.TRDateTime) AS DateTime) AS [Transmission End Date]
, HT.[ElapsedTime] AS [Time taken to send]
, HT.GoodPageCount AS Pages
, HT.[ChannelUsed]
FROM [dbo].History AS H (NOLOCK)
LEFT OUTER JOIN [dbo].HistoryTRX AS HT (NOLOCK) ON H.handle = HT.handle
)
SELECT
Calculate_Date AS [Full Calculated Date]
, CAST(Calculate_Date AS DATE) AS Calculated_Date
, CAST(DATEPART(YYYY , dhm.Calculate_Date) AS VARCHAR ) + '-' + RIGHT('0' + CAST(DATEPART(Month , dhm.Calculate_Date) AS VARCHAR) , 2) AS [Calculated Year-Month]
, CAST(DATEPART(YYYY , dhm.Calculate_Date) AS VARCHAR ) + '-' + RIGHT('0' + CAST(DATEPART(Week , dhm.Calculate_Date) AS VARCHAR) , 2) AS [Calculated Year-Week]
, CAST(DATEPART(YYYY , dhm.Calculate_Date) AS VARCHAR ) + '-' + RIGHT('0' + CAST(DATEPART(DAY , dhm.Calculate_Date) AS VARCHAR) , 2) AS [Calculated Year-Day]
, DATEPART(YYYY, dhm.Calculate_Date) AS [Calculated Year]
, RIGHT('0' + CAST(DATEPART(MM, dhm.Calculate_Date) AS VARCHAR) ,2) AS [Calculated Month]
, DATEPART(Week, dhm.Calculate_Date) AS [Calculated Week]
, DATEPART(DAY, dhm.Calculate_Date) AS [Calculated Day]
, RF.Transmission_ID
, RF.[Transmission Start Date]
, RF.[Transmission End Date]
, RIGHT('0' + CAST(DATEPART(HOUR , RF.[Transmission Start Date]) AS VARCHAR) ,2) + ':' + RIGHT('0' + CAST(DATEPART(Minute , RF.[Transmission Start Date]) AS VARCHAR) ,2) AS [Transmission Start Time]
, RIGHT('0' + CAST(DATEPART(HOUR , RF.[Transmission End Date]) AS VARCHAR) ,2) + ':' + RIGHT('0' + CAST(DATEPART(Minute , RF.[Transmission End Date]) AS VARCHAR) ,2) AS [Transmission End Time]
, RF.[Time taken to send]
, RF.Pages
, RF.[ChannelUsed]
FROM CTE_Text RF
INNER JOIN CTE_DayHourMinutes dhm ON
-- Join where the calculate_date is between the start and end date of the transmission date.
dhm.Calculate_Date >= RF.[Transmission Start Date]
AND
dhm.Calculate_Date <= RF.[Transmission End Date]
答案 0 :(得分:0)
我会根据你上面提到的代码以及对数据类型和表格模型,现有索引或pk等缺失的一些猜测来建议以下这些更改。更新/信息会很好。
我认为数据类型如下
创建表历史记录(
ObjectGuid uniqueidentifier
TRDateTime datetime
handle bigint
HistoryTRX
ElapsedTime int
GoodPageCount int
ChannelUsed int
handle bigint
尽管它没有改善整个查询,但CTE_DayHourMinutes更快更短:
; with CTE_DayHourMinutes(Calculate_Date) as (
select @startDate
union all
select DATEADD(MINUTE, 1, Calculate_Date) from CTE_DayHourMinutes
where Calculate_Date<DATEADD(MINUTE, 60*24-1, @currentDate)
)
Select Calculate_Date From CTE_DayHourMinutes
Option (MaxRecursion 0)
CTE_Text RF表扫描
您应该首先尽快加入[dbo] .History和CTE_DayHourMinutes,并尝试减少此CTE和历史记录表的范围。现在您可能正在扫描整个历史记录表+历史记录表格的全部或部分
LEFT OUTER JOIN [dbo] .HistoryTRX
当两个表之间没有匹配时,HT.ElapsedTime为空。因此,[传输结束日期]为空并且dhm.Calculate_Date&gt; = RF。[传输开始日期] AND dhm.Calculate_Date&lt; = RF。[传输结束日期]不匹配。您可能需要内部联接和/或需要查看/重新考虑您想要实现的目标。
尽可能删除演员和功能
看起来大多数都不需要。它们也阻止了索引的正确使用。
查看索引
它们是否设置正确且有用?