azure - Linq to Entities,当我尝试使用 group .. 时操作超时

标签 azure group-by linq-to-entities

我有以下代码:

        var statList = (from i in _dbContext.Screenshots
                       where EntityFunctions.TruncateTime(i.dateTimeServer.Value) >= startDate && EntityFunctions.TruncateTime(i.dateTimeServer.Value) <= endDate
                       group i by EntityFunctions.TruncateTime(i.dateTimeServer.Value)
                           into g
                           select new ScreenshotStatistic()
                           {
                               Date = g.Key.Value,
                               AllScreenshots = g.Count(),
                               ScreenshotsNoSilent = g.Where(p => p.version.IndexOf("silent") == 0).Count(),
                               ScreenshotsNoSilentWithViews = g.Where(p => p.version.IndexOf("silent") == 0 && p.viewsPage + p.viewsOriginal > 0).Count(),
                               ScreenshotsOnlySilent = g.Where(p => p.version.IndexOf("silent") >= 0).Count(),
                               ScreenshotsOnlySilentWithViews = g.Where(p => p.version.IndexOf("silent") >= 0 && p.viewsPage + p.viewsOriginal > 0).Count(),
                               ScreenshotsOnlyUploadViaSite = g.Where(p => p.version.IndexOf("UPLOAD_VIA_SITE") >= 0).Count(),
                               ScreenshotsOnlyUploadViaSiteWithViews = g.Where(p => p.version.IndexOf("UPLOAD_VIA_SITE") >= 0 && p.viewsPage + p.viewsOriginal > 0).Count()
                           }).ToList();

它对我的本地数据库运行良好,但当我尝试连接到 SQL Azure 时,出现“操作超时”。据我了解,我的请求没有得到优化。我怎样才能更好地完成请求?

表具有以下结构:

CREATE TABLE [dbo].[Screenshots](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [dateTimeClient] [datetime] NOT NULL,
    [name] [nvarchar](500) NOT NULL,
    [username] [varchar](50) NULL,
    [filename] [nvarchar](50) NULL,
    [description] [nvarchar](500) NULL,
    [version] [varchar](50) NULL,
    [lang] [varchar](50) NULL,
    [dateTimeServer] [datetime] NULL CONSTRAINT [DF_Screenshots_dateTimeServer]  DEFAULT (getdate()),
    [isPublic] [bit] NOT NULL CONSTRAINT [DF_Screenshots_isPublic]  DEFAULT ((0)),
    [viewsPage] [int] NOT NULL CONSTRAINT [DF_Screenshots_viewsPage_1]  DEFAULT ((0)),
    [viewsThumb] [int] NOT NULL CONSTRAINT [DF_Screenshots_viewsThumb_1]  DEFAULT ((0)),
    [viewsOriginal] [int] NOT NULL CONSTRAINT [DF_Screenshots_viewsOriginal_1]  DEFAULT ((0)),
    [statusID] [int] NOT NULL,
 CONSTRAINT [PK_Screenshots] PRIMARY KEY CLUSTERED 
(
    [id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

ALTER TABLE [dbo].[Screenshots]  WITH CHECK ADD  CONSTRAINT [FK_Screenshots_ScreenshotStatuses] FOREIGN KEY([statusID])
REFERENCES [dbo].[ScreenshotStatuses] ([ID])
ON UPDATE CASCADE
ON DELETE CASCADE
GO

ALTER TABLE [dbo].[Screenshots] CHECK CONSTRAINT [FK_Screenshots_ScreenshotStatuses]
GO

最佳答案

EntityFunctions.TruncateTime 正在被转换为:

convert (datetime2, convert(varchar(255), [dateTimeServer], 102) ,  102)

这导致您的查询为 non-sargable ,导致性能缓慢和超时。我建议进行以下更改

<小时/>

首先,我不明白为什么您需要截断 where 子句中的时间。我建议您进行此更改:

where i.dateTimeServer.Value >= startDate && i.dateTimeServer.Value <= endDate

这将防止数据库必须在每条记录上运行该函数。

<小时/>

如果查询仍然超时,我会将group by更改为:

group i by new { 
   i.dateTimeServer.Value.Year, 
   i.dateTimeServer.Value.Month, 
   i.dateTimeServer.Value.Day 
}

从功能上讲,这是相同的,但我相信它会产生更友好的翻译:

DATEPART (year, dateTimeServer), DATEPART (month, dateTimeServer) etc..
<小时/>

dateTimeServer添加索引

<小时/>

如果所有其他方法都失败,您将需要在表中添加一列,并截断时间部分。将其编入索引并在查询中使用它。

关于azure - Linq to Entities,当我尝试使用 group .. 时操作超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27890396/

相关文章:

azure - 更改 Azure 云服务环境变量而不发布

php - 无法使用 GROUP BY mysql 获取计数

pandas - 如何获取出现某个值的行?

c# - 将 LINQ to Entities 查询中的每个项目转换为接口(interface)的最佳方法是什么?

c# - 在 Linq to Entities 和 Linq to Object 之间共享表达式

azure - 发布没有 webjobs 的 web 应用程序

Azure 存储表传输速率超出 - 怎么办?

azure - 如何复制来自 Azure Web 应用程序的流量以进行测试

sql - 当日期存储很长时,如何按天分组?

asp.net-mvc - 将 LINQ to EF 投影到 View 模型时出现异常。获取 "only parameterless constructor and initializers"异常