【发布时间】:2020-02-09 09:57:07
【问题描述】:
我在 Microsoft Entity Framework Core 3.0 中运行一个相当简单的查询,如下所示:
var dbProfile = db.Profiles.Where(x => x.SiteId == Int32.Parse(id))
.Include(x => x.Interests)
.Include(x => x.Pets)
.Include(x => x.Networks)
.Include(x => x.PersonalityTraits)
.SingleOrDefault();
它在 EF Core 2.2.6 上运行良好,但在升级到 EF Core 3.0 时,此查询会立即针对 721 个配置文件运行,但对于至少一个配置文件,查询会超时:
Microsoft.Data.SqlClient.SqlException: '执行超时已过期。
在操作完成之前超时时间已过或服务器没有响应。'
然后我记录了发送到数据库服务器的实际查询:
https://stackoverflow.com/a/58348159/3850405
SELECT [t].[Id], [t].[Age], [t].[City], [t].[Country], [t].[County], [t].[DeactivatedAccount], [t].[Gender], [t].[HasPictures], [t].[LastLogin], [t].[MemberSince], [t].[PresentationUpdated], [t].[ProfileName], [t].[ProfilePictureUrl], [t].[ProfileText], [t].[SiteId], [t].[VisitorsCount], [i].[Id], [i].[Name], [i].[ProfileId], [p0].[Id], [p0].[Description], [p0].[Name], [p0].[ProfileId], [n].[Id], [n].[Name], [n].[NetworkId], [n].[ProfileId], [p1].[Id], [p1].[Name], [p1].[ProfileId]
FROM (
SELECT TOP(2) [p].[Id], [p].[Age], [p].[City], [p].[Country], [p].[County], [p].[DeactivatedAccount], [p].[Gender], [p].[HasPictures], [p].[LastLogin], [p].[MemberSince], [p].[PresentationUpdated], [p].[ProfileName], [p].[ProfilePictureUrl], [p].[ProfileText], [p].[SiteId], [p].[VisitorsCount]
FROM [Profiles] AS [p]
WHERE ([p].[SiteId] = '123') AND '123' IS NOT NULL
) AS [t]
LEFT JOIN [Interests] AS [i] ON [t].[Id] = [i].[ProfileId]
LEFT JOIN [Pets] AS [p0] ON [t].[Id] = [p0].[ProfileId]
LEFT JOIN [Networks] AS [n] ON [t].[Id] = [n].[ProfileId]
LEFT JOIN [PersonalityTraits] AS [p1] ON [t].[Id] = [p1].[ProfileId]
ORDER BY [t].[Id], [i].[Id], [p0].[Id], [n].[Id], [p1].[Id]
然后我尝试在 SSMS 中运行实际的 SQL,结果出现以下错误:
消息 1105,第 17 级,状态 2,第 1 行
无法为数据库“tempdb”中的对象“dbo.SORT 临时运行存储:140737692565504”分配空间,因为“PRIMARY”文件组已满。通过删除不需要的文件、删除文件组中的对象、向文件组中添加其他文件或为文件组中的现有文件设置自动增长来创建磁盘空间。
我的tempdb 现在已经完全填满了数据库磁盘。我已经尝试了 10 个其他 ID,并且相同的查询立即运行。
我尝试使用命令DBCC SHRINKDATABASE(tempdb, 10); 再次缩小 tempdb,它工作正常。但是,当我再次尝试运行查询时,同样的事情发生了。如果我跳过包括表格,一切都很好。这里可能有什么问题,我该如何解决?这是 EF Core 3.0 中的已知错误吗?查看 EF Core 2.2.6 中的查询,它对所有表执行像这样的单独选择:
SELECT [x.Interests].[Id], [x.Interests].[Name], [x.Interests].[ProfileId]
FROM [Interests] AS [x.Interests]
INNER JOIN (
SELECT TOP(1) [x0].[Id]
FROM [Profiles] AS [x0]
WHERE [x0].[SiteId] = '123'
ORDER BY [x0].[Id]
) AS [t] ON [x.Interests].[ProfileId] = [t].[Id]
ORDER BY [t].[Id]
【问题讨论】:
-
除非数据量很大,否则此查询应该可以正常运行。
tempdb爆炸通常表明表没有正确索引。您是否对所有外键字段和SiteId都有索引?此外,运行统计数据可能会产生巨大的影响。
标签: c# sql-server entity-framework entity-framework-core entity-framework-core-3.0