2015-06-24 38 views
-1

我有以下查詢運行速度非常慢,我感謝您的意見,以幫助我使這個運行更快。我沒有權限更改任何數據庫。我有兩個數據庫,1和2.如何使此查詢運行得更快?

數據庫1的呼叫者信息包括CallMemberID(可能少於或多於14位數字,可能包括逗號),車輛屬性(顏色,製造商,型號,狀態......) ,等

  1. 我除去逗號然後拿着CallMemberID的第一14位作爲成員Id使用:左(CallMemberID_mod,14)爲 'MEMBERID'

  2. 我還cancatenated車輛特性'車輛'以稍後查找每個MemberID使用的不同車輛的數量:Count(distinct(b.Vehicle))爲'Vehicle Count per成員' 數據庫2包含有關已提出投訴的成員的信息。它包括clubcode,CallMemberID和dait(它真的是成員打電話的日期)。 我發現使用每件投訴數目:COUNT(*)作爲「ComplaintsPerMemberId」組由MEMBERID 和我還發現每件ID調用之間使用的平均天數:AvgCallTimes:

WITH CallTimesOrdered (num, id, calldate) AS 
(
    SELECT ROW_NUMBER() OVER (PARTITION BY clubcode, CallMemberID ORDER BY dait DESC) AS RowNumber 
      ,CallMemberID 
      ,dait 
    FROM database1 
) 
,AvgCallTimes (id, timespan) AS 
(
    SELECT CurrentDate.id 
      ,DATEDIFF(d, CurrentDate.calldate, PriorDate.calldate) 
    FROM CallTimesOrdered CurrentDate 
      INNER JOIN CallTimesOrdered PriorDate ON PriorDate.num = CurrentDate.num - 1 AND PriorDate.id = CurrentDate.id 
) 

SELECT b.MemberID 
     ,AVG(d.timespan) AS AverageTimeBetweenCalls 
     ,COUNT(Distinct(b.Vehicle)) AS VehicleCountPerMember 
     ,ISNULL(vic.ComplaintsPerMemberId, 0) AS NumberOfComplaintsPerMember 
FROM (
      SELECT * 
        ,ISNULL(a.VehicleColor,'') + ' ' + ISNULL(a.VehicleManufactureYearDate, '') + ' ' + ISNULL(a.VehicleLicenseStateCode, '') + ' ' 
         + ISNULL(a.VehicleManufactureNumber, '') +' ' 
         + ISNULL(a.VehicleModelNumber, '') 
        AS Vehicle 
      FROM (
         SELECT c.CallMemberID 
           ,LEFT(CallMemberID_mod, 14) AS MemberID 
           ,c.VehicleColor 
           ,c.VehicleManufactureYearDate 
           ,c.VehicleLicenseStateCode 
           ,c.VehicleManufactureNumber 
           ,c.VehicleModelNumber 
           ,ID 
         FROM (
            SELECT LTRIM(REPLACE(CallMemberID, ',', '')) AS CallMemberID_mod 
              ,* 
            FROM database1 WITH (nolock) 
           ) c 
         WHERE LEN(CallMemberID_mod) >= 14 
        ) a 
     ) b 
     LEFT OUTER JOIN 
     (
      SELECT tab.MemberId 
        ,tab.ComplaintsPerMemberId 
      FROM (
         SELECT clubcode 
           ,MemberId 
           ,COUNT(*) AS ComplaintsPerMemberId 
         FROM database2 
         GROUP BY MemberId 
           ,clubcode 
        ) tab 
     ) vic On vic.MemberId = b.MemberId 
     LEFT JOIN 
     (
      SELECT Id 
        ,timespan 
      FROM AvgCallTimes 
     ) d ON d.ID = b.CallMemberID 
GROUP BY b.MemberID 
     ,vic.ComplaintsPerMemberId 
ORDER BY b.MemberID 
+0

您可以顯示查詢執行計劃?沒有這一點,任何人都無法幫助你。 – Dijkgraaf

+0

(1)我想建議,除去*和採取這確實在輸出中使用的那些許多屬性。很多地方,你用'*'。 (2)你爲什麼不在內部查詢中採用不同的車輛?然後你把它計算在內。嘗試使用CTE @計數ComplaintsPerMemberId。如果車輛選擇的結果較小超過5000行,然後儘量做到@表變量,因爲它駐留在內存中,讓你快速輸出。 –

回答

0

想幫你,但不能說有多少提高性能,而實際運行的數據或不看的執行計劃。

Declare @MemberVehicle Table 
(
    CallMemberID  Int 
    ,MemberID   Varchar(500) 
    ,Vehicle   Varchar(500) 
    ,ID     Int 
) 

WITH CallTimesOrdered (num, id, calldate) AS 
(
    SELECT ROW_NUMBER() OVER (PARTITION BY clubcode, CallMemberID ORDER BY dait DESC) AS RowNumber 
      ,CallMemberID 
      ,dait 
    FROM database1 
) 
,AvgCallTimes (id, timespan) AS 
(
    SELECT CurrentDate.id 
      ,DATEDIFF(d, CurrentDate.calldate, PriorDate.calldate) 
    FROM CallTimesOrdered CurrentDate 
      INNER JOIN CallTimesOrdered PriorDate ON PriorDate.num = CurrentDate.num - 1 AND PriorDate.id = CurrentDate.id 
) 

Insert Into @MemberVehicle(CallMemberID,MemberID,Vehicle,ID) 
Select a.CallMemberID 
     ,a.MemberID 
     ,ISNULL(a.VehicleColor,'') + ' ' + ISNULL(a.VehicleManufactureYearDate, '') + ' ' + ISNULL(a.VehicleLicenseStateCode, '') + ' ' 
      + ISNULL(a.VehicleManufactureNumber, '') +' ' 
      + ISNULL(a.VehicleModelNumber, '') 
      AS Vehicle 
     ,a.ID 
From (
      SELECT Distinct 
        c.CallMemberID 
        ,Left(LTRIM(REPLACE(CallMemberID, ',', '')), 14) AS MemberID 
        ,c.VehicleColor 
        ,c.VehicleManufactureYearDate 
        ,c.VehicleLicenseStateCode 
        ,c.VehicleManufactureNumber 
        ,c.VehicleModelNumber 
        ,c.ID 
      FROM database1 As c With (Nolock) 
      Where Len(LTRIM(REPLACE(CallMemberID, ',', ''))) >= 14 
     ) As a 

SELECT b.MemberID 
     ,AVG(d.timespan) AS AverageTimeBetweenCalls 
     ,Count(b.Vehicle) AS VehicleCountPerMember 
     ,ISNULL(vic.ComplaintsPerMemberId, 0) AS NumberOfComplaintsPerMember 
FROM @MemberVehicle As b 
     LEFT OUTER JOIN 
     (
      SELECT tab.MemberId 
        ,tab.ComplaintsPerMemberId 
      FROM (
         SELECT clubcode 
           ,MemberId 
           ,COUNT(*) AS ComplaintsPerMemberId 
         FROM database2 With (Nolock) 
         GROUP BY MemberId 
           ,clubcode 
        ) tab 
     ) vic On vic.MemberId = b.MemberId 
     LEFT JOIN 
     (
      SELECT Id 
        ,timespan 
      FROM AvgCallTimes With (Nolock) 
     ) d ON d.ID = b.CallMemberID 
GROUP BY b.MemberID 
     ,vic.ComplaintsPerMemberId 
ORDER BY b.MemberID