我有下面的查询,我把它放在一起,它运行得很糟糕(因为我相信你可以看到)。
我很确定这与我转换日期时间的方式有关,以便我可以参考昨天的数据。
dtInteractionLocalStartTime是一个日期时间字段,我希望它显示为mm / dd / yyyy而不是yyyy-mm-dd hh:mm:ss.sss
有关如何优化此问题的任何想法?我花了两天时间才弄清楚。
这是我的问题:
SELECT TOP 100 PERCENT
Date ,
CONVERT(varchar, VDN) AS VDN ,
COUNT(*) AS Calls ,
Avaya
FROM ( SELECT DISTINCT TOP 100 PERCENT
CONVERT(varchar,dtInteractionLocalStartTime,101) AS Date ,
vcVectorNumber AS VDN ,
iCompoundID ,
'CM03' AS Avaya
FROM NICEHUB3ADTM.nice_dw.dbo.vwNiceDBKitInteraction AS i
WHERE CONVERT(varchar(10) , dtInteractionLocalStartTime,101) = CONVERT(varchar(10),GETDATE()-1,101)
AND iMediaTypesId = 2
AND tiCallDirectionTypeID = 1
AND tiInteractionTypeID = 2
AND iInteractionOpenReasonID & 16 = 0
AND iInteractionOpenReasonID & 4 = 0
AND iInteractionID NOT IN ( SELECT iInteractionID
FROM NICEHUB3ADTM.nice_dw.dbo.vwException AS e
WHERE i.iInteractionID = iInteractionID
AND iExceptionTypeID IN (37, 12, 12310)
)
) AS derivedtbl_1
GROUP BY Date ,
CONVERT(varchar,VDN) ,
Avaya
ORDER BY Date ,
VDN
答案 0 :(得分:5)
如果你想要的只是日期而不是日期时间,只需使用:
CAST(yourDate AS DATE)
任何完成的格式化几乎都应该在sql之外完成,因为sql几乎没有针对这类事情进行优化,并且当你的视图逻辑工作进入模型时,最终会破坏关注点。
至少,将子查询中的转换调用更改为上面的转换,并且只将一个转换添加到最外面的选择(在分组之后)。如果你有能力在其他地方重构逻辑,我仍然会完全避免它。
答案 1 :(得分:4)
一些想法(因为“运行糟糕”并不是一个非常好的问题陈述):
全面摆脱top 100 percent
。这表示返回所有内容,这是SQL默认执行的操作。
使用select distinct
是代码异味。这强烈表明您要么提出错误或不正确的问题,要么您不理解查询中涉及的实体之间关系的基数。 SQL处理集。根据定义,集合是唯一的,所以如果你必须强迫唯一性,你几乎肯定会做错事。
您的派生表不是必需的
你正在针对同一列进行两次有点笨拙的测试。可以合并。
您正在执行相关子查询并使用not in (...)
而不是not exists (...)
您正在将vcVectorNumber转换为varchar。不知道它的数据类型,这似乎是无关紧要的:让应用程序处理转换为字符串。
转换datetime
列,同时进行比较。这将它转换为表达式,表达式不能使用索引,因此您可以阻止查询优化器使用任何合适的索引。不要那样做。如果可能的话,以不需要跳跃的方式测试datetime
列:between
是您的朋友。
这就是我重构你的查询的方法。我相信这会产生同样的结果:
select convert(date,i.dtInteractionLocalStartTime) as Date ,
i.vcVectorNumber as VDN ,
count(distinct i.iCompoundId) as Calls ,
'CM03' as Avaya
from NICEHUB3ADTM.nice_dw.dbo.vwNiceDBKitInteraction i
where i.dtInteractionLocalStartTime between dateadd(day ,-1 ,convert(datetime,convert(date,getdate()))) -- yesterday, midnight/start-of-day
and dateadd(ms ,-3 ,convert(datetime,convert(date,getdate()))) -- yesterday, end-of-day
and i.iMediaTypesId = 2
and i.tiCallDirectionTypeID = 1
and i.tiInteractionTypeID = 2
and i.iInteractionOpenReasonId & 0x0014 = 0 -- ( 16|4 is 20, 0x0014)
and not exists ( select *
from NICEHUB3ADTM.nice_dw.dbo.vwException e
where e.iInteractionID = i.iInteractionID
and e.iExceptionTypeID IN ( 37 , 12 , 12310 )
)
group by convert(date,i.dtInteractionLocalStartTime) ,
i.vcVectorNumber
order by convert(date,i.dtInteractionLocalStartTime) ,
i.vcVectorNumber
最后一个观察结果:4部分表名称表示可能使用跨服务器查询或链接服务器。如果是这样(根据我的经验),这可能是一项昂贵的操作。首先将远程数据吸收到本地临时表可以帮助提高性能。