我做了一些广泛的研究,我得出结论,DATEDIFF函数使我的查询运行得很慢。
以下是Entity Framework生成的查询,希望它看起来很可读。
这是生成T-SQL的Linq:
model.NewTotal1Week = ( from sdo in context.SubscriberDebitOrders
where
(
sdo.CampaignId == campaignId &&
( sdo.Status == ( Int32 ) DebitOrderStatus.New_Faulty ) &&
( SqlFunctions.DateDiff( "week", sdo.Collections.FirstOrDefault( c => c.TxnStatus == "U" ).ProcessDate, DateTime.Now ) <= 1 )
)
select sdo ).Count();
在下面的查询中,我想获得所有收藏品的COUNT个,这些收藏品从处理时间到今天的日期都在1周内。
有没有人可以帮我摆脱DATEDIFF功能?我在网上看过例子,但我无法适应我的情景,请原谅我,我不是很天才。
exec sp_executesql N'SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
COUNT(1) AS [A1]
FROM [dbo].[SubscriberDebitOrder] AS [Extent1]
OUTER APPLY (SELECT TOP (1)
[Extent2].[ProcessDate] AS [ProcessDate]
FROM [dbo].[Collections] AS [Extent2]
WHERE ([Extent1].[Id] = [Extent2].[DebitOrderId]) AND (''U'' = [Extent2].[TxnStatus]) ) AS [Limit1]
WHERE ([Extent1].[CampaignId] = @p__linq__0) AND (3 = [Extent1].[Status]) AND ((DATEDIFF(week, [Limit1].[ProcessDate], SysDateTime())) <= 1)
) AS [GroupBy1]',N'@p__linq__0 int',@p__linq__0=3
go
提前致谢。
答案 0 :(得分:4)
它不仅仅是DATEDIFF,列上的任何函数都会导致查询在基础表/索引上执行SCAN
DATEDIFF(week, [Limit1].[ProcessDate], SysDateTime())) <=1
以上逻辑是否在上周获取数据?您也可以在上面编写,而不必在ProcessDate Column周围添加函数。
[Limit1].[ProcessDate] > SysDateTime()-7
答案 1 :(得分:3)
这是您的查询:
SELECT GroupBy1.A1 AS C1
FROM (SELECT COUNT(1) AS[A1
FROM dbo.SubscriberDebitOrder AS Extent1 OUTER APPLY
(SELECT TOP (1) Extent2.ProcessDate
FROM [dbo].Collections Extent2
WHERE (Extent1.Id = Extent2.DebitOrderId AND
'U' = Extent2.TxnStatus
) AS [Limit1]
WHERE (Extent1.CampaignId = @p__linq__0) AND (3 = Extent1.Status) AND
(DATEDIFF(week, Limit1.ProcessDate, SysDateTime()) <= 1)
) GroupBy1;
如其他地方所述,您应该更改日期逻辑并删除外部查询:
SELECT COUNT(1) AS A1
FROM dbo.SubscriberDebitOrder AS Extent1 OUTER APPLY
(SELECT TOP (1) Extent2.ProcessDate
FROM [dbo].Collections Extent2
WHERE (Extent1.Id = Extent2.DebitOrderId AND
'U' = Extent2.TxnStatus
) AS limit1
WHERE (Extent1.CampaignId = @p__linq__0) AND (3 = Extent1.Status) AND
Limit1.ProcessDate <= DATEADD(-1, week, GETDATE())
非常重要的说明:这与您的查询不完全相同。您的原始查询计算了两个日期之间的周边界数。这取决于datefirst
,但它通常是周六或周日晚上的数量。
根据您的描述,上述内容更为正确。
接下来,您需要Collections(DebitOrderId, TxnStatus, ProcessDate)
和SubscriberDebitOrder(CampaignId, Status)
上的索引。