我有下面的 4 个 SQL 查询,最后将它们组合成一个结果集。
我猜测,因为我在每个 SQL 部分中对相同的表进行操作,所以有一种很酷的方法可以从一个统一的 SQL 查询中获取结果。
目前我是这样做的:
select
[date] = CONVERT(DATE, M.crdate),
[tally sent to smc w/ attachment] = count(*) ,
[total MB size] = sum(cast(AD.Size as decimal (10,2)) )/1024/1024
into #tmp_Attachments_Sent_To_smc
from AttachmentDetail AD
inner join MessageAttachment MA on AD.AttachmentId = MA.AttachmentId
inner join MessageRecipient MR on MA.MessageId = MR.MessageId
inner join Message M on MR.MessageId = M.id
where AD.isinline <>1 and MR.RecipientTypeId =2 and left(mr.EmailAddress,4)='smc+'
GROUP BY CONVERT(DATE, M.crdate)
ORDER BY [date] DESC;
--select * from #tmp_Attachments_Sent_To_smc
select
[date] = CONVERT(DATE, M.crdate),
[tally sent from smc w/ attachment] = count(*) ,
[total MB size] = sum(cast(AD.Size as decimal (10,2)) )/1024/1024
into #tmp_Attachments_Sent_from_smc
from AttachmentDetail AD
inner join MessageAttachment MA on AD.AttachmentId = MA.AttachmentId
inner join MessageRecipient MR on MA.MessageId = MR.MessageId
inner join Message M on MR.MessageId = M.id
where AD.isinline <>1 and MR.RecipientTypeId =1 and left(mr.EmailAddress,4)='smc+'
GROUP BY CONVERT(DATE, M.crdate)
ORDER BY [date] DESC;
select
[date] = CONVERT(DATE, M.crdate),
[grand total sent to smc] = count(*) ,
[total MB size sent to smc] = sum(cast(Size as decimal ) )/1024/1024
into #tmp_Sent_to_smc
from Message M
where MessageSourceId=2
GROUP BY CONVERT(DATE, crdate)
ORDER BY [date] DESC;
select
[date] = CONVERT(DATE, M.crdate),
[grand total sent from smc] = count(*) ,
[total MB size sent from smc] = sum(cast(Size as decimal ) )/1024/1024
into #tmp_Sent_from_smc
from Message M
where MessageSourceId=1
GROUP BY CONVERT(DATE, crdate)
ORDER BY [date] DESC;
select A.* ,
B.[tally sent from smc w/ attachment] ,
B.[total MB size],
C.[grand total sent from smc] ,
C.[total MB size sent from smc],
D.[grand total sent to smc] ,
D.[total MB size sent to smc]
from #tmp_Attachments_Sent_To_smc A
join #tmp_Attachments_Sent_from_smc B on A.date = b.date
join #tmp_Sent_from_smc C on A.date = C.date
join #tmp_Sent_to_smc D on A.date = D.date
drop table #tmp_Attachments_Sent_To_smc
drop table #tmp_Attachments_Sent_from_smc
drop table #tmp_Sent_from_smc
drop table #tmp_Sent_to_smc
作为第一步,我会看看您是否可以消除临时表。我喜欢CTE的,但它们并不总是提供更好的性能。
否则,可能会损害您的性能的是 WHERE 和 GROUP BY ( 中的转换
CONVERT(date, M.crdate)
CAST(AD.Size AS decimal(10, 2)
。这些可能会导致对您造成伤害的表扫描。如果您不能将现有数据类型修改为意味着存储那些计算的项目。我正在盯着
LEFT(mr.EmailAddress, 4)
看,我认为这也会强制进行表扫描,但我认为它可以通过mr.EmailAddress LIKE 'smc+%'
至少应该是 SARGAble 来修复。到那时,您应该能够查看您的查询计划并确定索引是否有帮助。
此外,为您的表添加适当的模式前缀。我认为它是 dbo,但据我了解,这将有助于计划缓存重用。
笔记
billinkc
是正确的。在 varchar 列上使用 LEFT 函数不是SARGable,因此请改用 LIKE 。支持 SARG 意味着可以在搜索参数中将条件用于索引DATE
如果您正在处理 1000 个唯一日期(3 年的数据),则在临时表上创建索引将有助于查询CAST(.. to decimal)
需要一个说明符。否则,它等同于 decimal(18,0)。(这对于避免整数除法仍然有用)单个查询
原始查询批次:
我使用这个 DDL 和 DML 进行测试: