我目前正在运行此查询:
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%。
答案 0 :(得分: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
- 以便时间维度在等于值上连接,而不是在一系列值之间的值上。
如果这不能显着提高性能,那么我建议您在现有查询上创建索引视图,并从索引视图中选择新查询 - 您可以找到有关创建索引视图here的更多信息,是关于其限制的一些信息here。
答案 1 :(得分: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,
其中im
是incoming_message
的简短别名。
答案 2 :(得分: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
答案 3 :(得分: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)