2015-06-24 41 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