【问题标题】:How to optimize this linq query? (with OrderBy and ThenBy)如何优化这个 linq 查询? (使用 OrderBy 和 ThenBy)
【发布时间】:2012-03-28 23:05:31
【问题描述】:

我目前在一张表中有大约 90k 行。在我执行清理并将所有行放入“历史表”之前,它会增长大约 1kk ~ 5kk。因此,当我运行以下查询时(MyEntities 是一个 ObjectSet):

MyEntities.Skip(amount * page).Take(amount).ToList();

此查询大约需要 1.2 秒...但是当我使用 OrderBy 和 ThenBy 运行以下查询时:

MyEntities.OrderBy(b => b.Day).ThenBy(b => b.InitialHour).Skip(amount * page).Take(amount).ToList();

此查询大约需要 5.7 秒。有没有办法优化第二个查询?

【问题讨论】:

  • 你在数据库中的表上有合适的索引吗?
  • 表的后备存储是什么?如果是 SQL,那么您可能只需要一些索引
  • 你为什么要强迫 Linq 做数据库查询应该做的工作? SQL 查询/过程在处理如此大量的记录方面效率更高。
  • @SpikeX:是什么让您认为数据库没有这样做? LINQ 的好处之一是在 C# 中指定查询,但它执行为 SQL。
  • @Servy:实际上我怀疑 LINQ to Objects 相当能够在 5 秒内处理 90K 条记录。对于一台现代机器来说,这已经是 很多 的时间了,而 90K 记录真的不算多。

标签: c# linq optimization


【解决方案1】:

一些建议:

  • 检查它是否真的正在在数据库中发生(而不是获取所有实体,然后排序)
  • 确保 DayInitialHour 均已编入索引。
  • 检查生成的 SQL 没有做任何疯狂的事情(检查查询计划)

编辑:好的,看起来MyEntities 实际上被声明为IEnumerable<MyEntity>,这意味着一切都将在进程中完成...您所有的LINQ调用都将通过@987654325 @ 等,而不是Queryable.Select 等。只需将MyEntities已声明 类型更改为IQueryable<MyEntity>,然后看着它飞起来......

【讨论】:

  • 我用Day和InitialHour创建了一个索引,查询耗时5.5s……我去看看生成了什么sql。
  • 运行第二个查询后,我调用MyEntities.ToTraceString(),查询为SELECT [All table columns] FROM Tickets。为什么没有 ORDER BY, TOP...?
  • @ViniciusOttoni:那么,MyEntities已声明 类型是什么?是IEnumerable<MyEntity>吗?
  • 这是IEnumerable<MyEntity>ObjectSet<MyEntity> 的演员表。
  • @ViniciusOttoni:是的,那就是问题所在。你想要IQueryable<MyEntity>。我怀疑你会发现这要快得多:)
【解决方案2】:

为了从您的数据库中读取数据,创建自定义 SQL 视图通常是一个好主意,例如您要填充的每个网格一个视图和每个表单一个视图。

在此示例中,您将创建一个为您进行排序的视图,然后将该视图映射到 Entity Framework 中的一个实体,然后使用 LINQ 查询该实体。

这很好,干净,可读,可维护并且尽可能优化。

祝你好运!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-10
    • 1970-01-01
    • 2011-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多