1

我目前正在运行此查询:

SELECT  Time_ID,
    Site_Type_ID,
    Abandoned_ID,
    WorkType_ID,
    SUM (staging.dbo.incoming_measure.ring_time) AS Ring_Time,
    SUM (staging.dbo.incoming_measure.hold_time) As Hold_Time,
    SUM (staging.dbo.incoming_measure.talk_time) AS Talk_Time,
    SUM (staging.dbo.incoming_measure.acw_time) AS ACW_Time,
    COUNT(*) CallCount
FROM incoming_measure
INNER JOIN DataMartEnd.dbo.Time_Dim 
        ON incoming_measure.StartTimeDate BETWEEN Time_Dim.Time_Start and 
                                                  Time_Dim.Time_End
INNER JOIN datamartend.dbo.Site_Type_Dim 
        ON incoming_measure.DBID = Site_Type_Dim.Site_Type_Code
INNER JOIN datamartend.dbo.Abandoned_Call_Dim 
        ON incoming_measure.Abandoned = Abandoned_Call_Dim.abandoned_value
INNER JOIN DataMartEnd.dbo.Work_Type_Dim 
        ON incoming_measure.DBID = work_type_dim.MIG_Site_ID AND
           Work_Type_Dim.Work_Type_Code = incoming_measure.Queue AND
           incoming_measure.StartTimeDate BETWEEN Work_Type_Dim.DimEffectiveStartDtm AND
                                                  Work_Type_Dim.DimEffectiveEndDtm
group by time_id, Site_Type_ID, Abandoned_ID, WorkType_ID

它返回正确的结果,但运行大约需要 8 分钟,我只是想知道是否有人对我如何加快查询有任何建议?主要问题是如果这是我必须向客户展示最终结果的项目的一部分,并且我只能展示 10 分钟(大学规则),并且此查询约占项目的 30%。

估计执行的大部分是 SORT,占 57%。

4

4 回答 4

2

如果这样重写,您可能会发现查询的性能更好:

SELECT
    Time_ID,
    Site_Type_ID,
    Abandoned_ID,
    WorkType_ID,
    SUM (im.ring_time) AS Ring_Time,
    SUM (im.hold_time) As Hold_Time,
    SUM (im.talk_time) AS Talk_Time,
    SUM (im.acw_time) AS ACW_Time,
    COUNT(*) CallCount
FROM incoming_measure im
INNER JOIN DataMartEnd.dbo.Time_Dim td
        ON dateadd(mi,
                   15*floor(datediff(mi,
                                     dateadd(dd, datediff(dd,0,im.StartTimeDate), 0),
                                     im.StartTimeDate ) / 15),
                   dateadd(dd, datediff(dd,0,im.StartTimeDate), 0) 
                  ) = td.Time_Start
INNER JOIN datamartend.dbo.Site_Type_Dim std
        ON im.DBID = std.Site_Type_Code
INNER JOIN datamartend.dbo.Abandoned_Call_Dim acd
        ON im.Abandoned = acd.abandoned_value
INNER JOIN DataMartEnd.dbo.Work_Type_Dim wtd
        ON im.DBID = wtd.MIG_Site_ID AND
           im.Queue = wtd.Work_Type_Code AND
           im.StartTimeDate BETWEEN wtd.DimEffectiveStartDtm AND wtd.DimEffectiveEndDtm
group by time_id, Site_Type_ID, Abandoned_ID, WorkType_ID

- 以便时间维度连接在一个等于值上,而不是连接在一个值范围之间的值上。

如果这不能显着提高性能,那么我建议在现有查询上创建索引视图,并从索引视图中选择作为新查询 - 您可以在此处找到有关创建索引视图的更多信息,同时在此处提供有关其限制的一些信息.

于 2013-04-01T17:45:33.623 回答
1

我认为性能问题是由于以下连接造成的:

FROM incoming_measure
INNER JOIN DataMartEnd.dbo.Time_Dim 
        ON incoming_measure.StartTimeDate BETWEEN Time_Dim.Time_Start and 
                                                  Time_Dim.Time_End

什么是颗粒度Time_Dim?的粒度是StartTimeDate多少?名称表明一个以天为单位,另一个以小时、分钟或秒为单位。这可能会导致匹配许多其他记录。

如果您有时间维度,为什么要存储常规日期?如果您有数据库日期时间,为什么要使用时间维度表?

此外,您应该给每个表一个可读的别名。试图找出类似的东西:

SUM (staging.dbo.incoming_measure.ring_time) AS Ring_Time,

比:

SUM (im.ring_time) AS Ring_Time,

哪里imincoming_message.

于 2013-04-01T13:10:35.070 回答
0

试试这个可能对你有帮助。

SELECT * FROM 
(SELECT  
ROW_NUMBER() OVER( PARTITION BY time_id, Site_Type_ID, Abandoned_ID, WorkType_ID ORDER BY time_id) No,
Time_ID,
    Site_Type_ID,
    Abandoned_ID,
    WorkType_ID,
    SUM (staging.dbo.incoming_measure.ring_time) OVER( PARTITION BY time_id, Site_Type_ID, Abandoned_ID, WorkType_ID) AS Ring_Time,
    SUM (staging.dbo.incoming_measure.hold_time) OVER( PARTITION BY time_id, Site_Type_ID, Abandoned_ID, WorkType_ID) As Hold_Time,
    SUM (staging.dbo.incoming_measure.talk_time) OVER( PARTITION BY time_id, Site_Type_ID, Abandoned_ID, WorkType_ID) AS Talk_Time,
    SUM (staging.dbo.incoming_measure.acw_time) OVER( PARTITION BY time_id, Site_Type_ID, Abandoned_ID, WorkType_ID) AS ACW_Time,
    COUNT(1)  OVER( PARTITION BY time_id, Site_Type_ID, Abandoned_ID, WorkType_ID) CallCount
FROM incoming_measure
INNER JOIN DataMartEnd.dbo.Time_Dim 
        ON incoming_measure.StartTimeDate BETWEEN Time_Dim.Time_Start and 
                                                  Time_Dim.Time_End
INNER JOIN datamartend.dbo.Site_Type_Dim 
        ON incoming_measure.DBID = Site_Type_Dim.Site_Type_Code
INNER JOIN datamartend.dbo.Abandoned_Call_Dim 
        ON incoming_measure.Abandoned = Abandoned_Call_Dim.abandoned_value
INNER JOIN DataMartEnd.dbo.Work_Type_Dim 
        ON incoming_measure.DBID = work_type_dim.MIG_Site_ID AND
           Work_Type_Dim.Work_Type_Code = incoming_measure.Queue AND
           incoming_measure.StartTimeDate BETWEEN Work_Type_Dim.DimEffectiveStartDtm AND
                                                  Work_Type_Dim.DimEffectiveEndDtm
                                                 ) AS T1 WHERE No = 1 

或者

SELECT  Time_ID,
    Site_Type_ID,
    Abandoned_ID,
    WorkType_ID,
    SUM (staging.dbo.incoming_measure.ring_time) AS Ring_Time,
    SUM (staging.dbo.incoming_measure.hold_time) As Hold_Time,
    SUM (staging.dbo.incoming_measure.talk_time) AS Talk_Time,
    SUM (staging.dbo.incoming_measure.acw_time) AS ACW_Time,
    COUNT(1) CallCount
FROM incoming_measure
INNER JOIN DataMartEnd.dbo.Time_Dim 
        ON incoming_measure.StartTimeDate BETWEEN Time_Dim.Time_Start and 
                                                  Time_Dim.Time_End
INNER JOIN datamartend.dbo.Site_Type_Dim 
        ON incoming_measure.DBID = Site_Type_Dim.Site_Type_Code
INNER JOIN datamartend.dbo.Abandoned_Call_Dim 
        ON incoming_measure.Abandoned = Abandoned_Call_Dim.abandoned_value
INNER JOIN DataMartEnd.dbo.Work_Type_Dim 
        ON incoming_measure.DBID = work_type_dim.MIG_Site_ID AND
           Work_Type_Dim.Work_Type_Code = incoming_measure.Queue AND
           incoming_measure.StartTimeDate BETWEEN Work_Type_Dim.DimEffectiveStartDtm AND
                                                  Work_Type_Dim.DimEffectiveEndDtm
group by time_id, Site_Type_ID, Abandoned_ID, WorkType_ID
于 2013-04-01T13:01:27.130 回答
0

您需要以下字段的索引:

Time_Dim.Time_ID

incoming_measure.DBID
incoming_measure.Queue
incoming_measure.Abandoned
incoming_measure.StartTimeDate

Site_Type_Dim.Site_Type_ID
Site_Type_Dim.Site_Type_Code

Abandoned_Call_Dim.Abandoned_ID
Abandoned_Call_Dim.abandoned_value

Work_Type_Dim.WorkType_ID
Work_Type_Dim.Work_Type_Code
work_type_dim.MIG_Site_ID

我不完全确定索引中字段的顺序,因此您可能需要进行试验,但我建议:

create index Time_Dim_Time_ID on Time_Dim (Time_ID)
create index incoming_measure_index on (DBID, Queue, Abandoned, StartTimeDate)
create index Site_Type_index on Site_Type_Dim (Site_Type_ID, Site_Type_Code)
create index Abandoned_Call_index on Abandoned_Call_Dim (Abandoned_ID, abandoned_value)
create index Work_Type_index on Work_Type_Dim (WorkType_ID, Work_Type_Code, MIG_Site_ID)
于 2013-04-01T13:14:19.787 回答