Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# SQL Server-DATEDIFF函数花费的时间太长_C#_Sql_Sql Server_Entity Framework_Linq To Sql - Fatal编程技术网

C# SQL Server-DATEDIFF函数花费的时间太长

C# SQL Server-DATEDIFF函数花费的时间太长,c#,sql,sql-server,entity-framework,linq-to-sql,C#,Sql,Sql Server,Entity Framework,Linq To Sql,我做了一些广泛的研究,得出的结论是DATEDIFF函数使我的查询运行得非常慢 下面是实体框架生成的查询,看起来确实可读性很好 以下是生成T-SQL的Linq: model.NewTotal1Week = ( from sdo in context.SubscriberDebitOrders where ( sdo.CampaignId == cam

我做了一些广泛的研究,得出的结论是DATEDIFF函数使我的查询运行得非常慢

下面是实体框架生成的查询,看起来确实可读性很好

以下是生成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();
在下面的查询中,我想对从处理到今天的一周内的所有收集进行计数

有人能帮我去掉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

提前感谢。

这不仅仅是DATEDIFF,列上的任何函数都会导致查询对基础表/索引进行扫描

DATEDIFF(week, [Limit1].[ProcessDate], SysDateTime())) <=1

这不仅仅是DATEDIFF,列上的任何函数都会导致查询对基础表/索引进行扫描

DATEDIFF(week, [Limit1].[ProcessDate], SysDateTime())) <=1
这是您的查询:

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,但通常是周六或周日晚上的数量

根据你的描述,上面的说法更为正确

接下来,您需要有关CollectionDebitorDerId、TxnStatus、ProcessDate和SubscriberDebitOrderCampaignId、Status的索引。

这是您的查询:

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,但通常是周六或周日晚上的数量

根据你的描述,上面的说法更为正确


接下来,您需要有关CollectionDebitorDerId、TxnStatus、ProcessDate和SubscriberDebitOrderCampaignId、Status的索引。

显示生成此SQL的代码。@Hakumanatata,我已经用生成T-SQLshow的Linq更新了OP。显示生成此SQL的代码。@Hakumanatata,我已经用Linq更新了我的OP,它生成了T-SQLI,就像你的解决方案一样+1,但您必须将SysDateTime转换为DATETIME,或者最好使用GETDATE。。。使用DATETIME2您无法执行简单的添加…此datediff的逻辑与原始逻辑不完全相同。感谢您指出GETDATE@Balmukund Lakhani,我尝试了您的解决方案,并用GETDATE替换了SysDateTime,查询仍然需要1分钟。发生的事情让我有点恼火。根据OP id为27的活动的收集量较少,只有1434个。当我对另一个收集量超过40K的活动执行相同的查询时,查询在30秒内完成。不太确定这里会发生什么。。。有什么建议吗?我喜欢你的解决方案+1,但您必须将SysDateTime转换为DATETIME,或者最好使用GETDATE。。。使用DATETIME2您无法执行简单的添加…此datediff的逻辑与原始逻辑不完全相同。感谢您指出GETDATE@Balmukund Lakhani,我尝试了您的解决方案,并用GETDATE替换了SysDateTime,查询仍然需要1分钟。发生的事情让我有点恼火。根据OP id为27的活动的收集量较少,只有1434个。当我对另一个收集量超过40K的活动执行相同的查询时,查询在30秒内完成。不太确定这里会发生什么。。。有什么建议吗?我的SQL Server不允许我:DATEADD-1、week、GETDATE。但是我确实把它改成了DATEADDweek,-1,GETDATE,在我应该得到的时候,我没有得到任何结果。有什么建议吗?Gordon Linoff,谢谢你引导我为你建议的专栏添加索引。结果现在在5秒内返回…我的SQL Server不允许我:DATEADD-1、week、GETDATE。但是我确实把它改成了DATEADDweek,-1,GETDATE,在我应该得到的时候,我没有得到任何结果。有什么建议吗?Gordon Linoff,谢谢你引导我为你建议的专栏添加索引。结果现在在5秒内返回。。。