2015-08-03 26 views
2

我有一個腳本這對於一個給定的時間內只返回有問題的行和複製歷時超過60秒發送的任何行。這是從實踐中取得了以下連接:SQL Server來增加腳本性能聯接

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相匹配。唯一的問題是需要10分鐘才能返回100條記錄。最後,該腳本應在內部系統如果不是數百萬行的其中可能有成千上萬,我們應期待通過三個月的數據的拉動使用。

我還要提到,我已經測試腳本的其餘部分和每一個工作正常,並沒有性能問題runnign必要的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] 
+4

太寬了。顯示更多代碼(如CTE)以及一些基準/性能分析數據 – Amit

+0

...以及包括索引和執行計劃的相關表結構 –

+0

處理60sec條件的邏輯在哪裏? – Bulat

回答

0

我建議以下,根據你把上面的代碼,這些變化和所缺少的,如數據類型和表格模型,現有的索引或PK,等更新/信息的一些猜測會好的。

  • 我認爲該數據類型是如下

    • 創建錶的歷史(

      ObjectGuid uniqueidentifier 
      TRDateTime datetime 
      handle bigint 
      
    • HistoryTRX

      ElapsedTime int 
      GoodPageCount int 
      ChannelUsed int 
      handle bigint 
      
  • Altough它不會提高整個查詢,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和歷史表的範圍。現在你可能掃描整個History表+全部或部分HistoryTRX

  • LEFT OUTER JOIN [DBO] .HistoryTRX

    時,有2個表之間不匹配,HT.ElapsedTime爲空。因此[傳輸結束日期]是零和dhm.Calculate_Date> = RF。[傳輸開始日期] AND dhm.Calculate_Date < = RF。[傳輸結束日期]不匹配。您可能需要內部連接和/或需要審查/重新考慮您想實現的目標。

  • 卸下演員和功能儘可能

    它看起來像他們大多是沒有必要的。他們也阻止索引的正確使用。

  • 查看您的索引

    他們是否設置正確,有用?