Sql server 2008 如何使此查询运行得更快?

Sql server 2008 如何使此查询运行得更快?,sql-server-2008,Sql Server 2008,我有下面的查询运行非常慢,我感谢您的评论,以帮助我加快运行速度。我没有修改任何数据库的权限。我有两个数据库,1和2 数据库1包含呼叫者信息,包括CallMemberID(可能小于或大于14位,可能包括逗号)、车辆属性(颜色、制造商、型号、状态等) 我删除了逗号,然后使用:left(CallMemberID_mod,14)作为'MemberId'将CallMemberID的前14位数字作为MemberId 我还将车辆属性取消为“车辆”,以便稍后使用:Count(distinct(b.vehicle

我有下面的查询运行非常慢,我感谢您的评论,以帮助我加快运行速度。我没有修改任何数据库的权限。我有两个数据库,1和2

数据库1包含呼叫者信息,包括CallMemberID(可能小于或大于14位,可能包括逗号)、车辆属性(颜色、制造商、型号、状态等)

  • 我删除了逗号,然后使用:left(CallMemberID_mod,14)作为'MemberId'将CallMemberID的前14位数字作为MemberId

  • 我还将车辆属性取消为“车辆”,以便稍后使用:Count(distinct(b.vehicle))作为“每个成员的车辆计数”查找每个成员的不同车辆的数量ID 数据库2包含有关已拨打投诉电话的成员的信息。它包括clubcode、CallMemberID和dait(实际上是成员进行呼叫的日期)。 我使用:COUNT(*)作为“ComplaintsPerMemberId”组按MemberID查找每个成员的投诉数量 我还使用:AvgCallTimes找到了每个成员id的平均通话间隔天数:


  • 试图帮助您,但在不使用实际数据运行或不查看执行计划的情况下,无法说明性能提高了多少

    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
    

    您可以显示查询执行计划吗?没有这些,任何人都几乎不可能帮助您。(1)我想建议,删除*并获取输出中真正使用的许多属性。这么多地方,你都用了“*”。(2) 为什么不在内部查询时使用不同的车辆。那你就算了。尝试使用CTE@taking count of ComplaintsPerMemberId。如果vehicle select结果小于5000行,则尝试将其设为@table变量,因为它驻留在内存中并提供快速输出。
    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