gpt4 book ai didi

c# - 我怎样才能提高这个 LINQ 的性能?

转载 作者:太空狗 更新时间:2023-10-29 23:50:33 26 4
gpt4 key购买 nike

更新感谢@usr,我只需更改

就可以将其缩短到约 3 秒
.Select(
log => log.OrderByDescending(
d => d.DateTimeUTC
).FirstOrDefault()
)

    .Select(
log => log.OrderByDescending(
d => d.Id
).FirstOrDefault()
)

我有一个包含两个表的数据库 - 日志和收集器 - 我正在使用 Entity Framework 来读取它们。有86个收集器记录,每个收集器有50000+条对应的Log记录。

我想获取每个收集器的最新日志记录,这很容易用这个 SQL 完成

SELECT CollectorLogModels_1.Status, CollectorLogModels_1.NumericValue,
CollectorLogModels_1.StringValue, CollectorLogModels_1.DateTimeUTC,
CollectorSettingsModels.Target, CollectorSettingsModels.TypeName
FROM
(SELECT CollectorId, MAX(Id) AS Id
FROM CollectorLogModels GROUP BY CollectorId) AS RecentLogs
INNER JOIN CollectorLogModels AS CollectorLogModels_1
ON RecentLogs.Id = CollectorLogModels_1.Id
INNER JOIN CollectorSettingsModels
ON CollectorLogModels_1.CollectorId = CollectorSettingsModels.Id

这需要大约 2 秒的时间来执行。

我能得到的最接近 LINQ 的是以下内容

var logs = context.Logs.Include(co => co.Collector)
.GroupBy(
log => log.CollectorId, log => log
)
.Select(
log => log.OrderByDescending(
d => d.DateTimeUtc
).FirstOrDefault()
)
.Join(
context.Collectors,
(l => l.CollectorId),
(c => c.Id),
(l, c) => new
{
c.Target,
DateTimeUTC = l.DateTimeUtc,
l.Status,
l.StringValue,
CollectorName = c.TypeName
}
).OrderBy(
o => o.Target
).ThenBy(
o => o.CollectorName
)
;

这会产生我想要的结果,但需要大约 35 秒才能执行。

这就变成了下面的SQL

SELECT 
[Distinct1].[CollectorId] AS [CollectorId],
[Extent3].[Target] AS [Target],
[Limit1].[DateTimeUtc] AS [DateTimeUtc],
[Limit1].[Status] AS [Status],
[Limit1].[StringValue] AS [StringValue],
[Extent3].[TypeName] AS [TypeName]
FROM (SELECT DISTINCT
[Extent1].[CollectorId] AS [CollectorId]
FROM [dbo].[CollectorLogModels] AS [Extent1] ) AS [Distinct1]
OUTER APPLY (SELECT TOP (1) [Project2].[Status] AS [Status], [Project2].[StringValue] AS [StringValue], [Project2].[DateTimeUtc] AS [DateTimeUtc], [Project2].[CollectorId] AS [CollectorId]
FROM ( SELECT
[Extent2].[Status] AS [Status],
[Extent2].[StringValue] AS [StringValue],
[Extent2].[DateTimeUtc] AS [DateTimeUtc],
[Extent2].[CollectorId] AS [CollectorId]
FROM [dbo].[CollectorLogModels] AS [Extent2]
WHERE [Distinct1].[CollectorId] = [Extent2].[CollectorId]
) AS [Project2]
ORDER BY [Project2].[DateTimeUtc] DESC ) AS [Limit1]
INNER JOIN [dbo].[CollectorSettingsModels] AS [Extent3] ON [Limit1].[CollectorId] = [Extent3].[Id]
ORDER BY [Extent3].[Target] ASC, [Extent3].[TypeName] ASC

如何使性能更接近于仅使用 SQL 可实现的性能?

最佳答案

在您的原始 SQL 中,您可以从与 MAX(ID) 不同的行中选择一个集合 DateTimeUTC。这可能是一个错误。 EF没有这个问题。它在语义上并不相同,这是一个更难的查询。

如果您将 EF 查询重写为在结构上与 SQL 查询相同,您将获得相同的性能。我在这里看不到任何 EF 不支持的内容。

同时使用 EF 计算 max(id) 并加入。

关于c# - 我怎样才能提高这个 LINQ 的性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31047182/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com