我有以下代码:
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/