LINQ / SQL性能问题有很长的列表

时间:2009-11-16 16:25:18

标签: sql linq performance

在我们的数据库中,我们有一个包含超过100000个条目的表,但大多数时候我们只需要它的一部分。我们通过一个非常简单的查询来做到这一点。

items.AddRange(from i in this
    where i.ResultID == resultID && i.AgentID == parentAgentID
    orderby i.ChangeDate descending
    select i);

在此查询之后,我们得到一个包含最多500个项目的列表。但即使从这个结果我们只需要最新的和以下的项目。我的同事用这个很简单:

items[0];
items[1];

正常工作,因为查询结果已按日期排序。但总体表现非常糟糕。甚至需要几秒钟。

我的想法是在查询结束时添加.Take(2)但我的同事说这没有任何区别。

items.AddRange((from i in resultlist
    where i.ResultID == resultID && i.AgentID == parentAgentID
    orderby i.ChangeDate descending
    select i).Take(2));

我们还没有尝试过,我们仍在寻找其他方法来加快速度。但数据库编程不是我们强有力的一面,任何建议都会很棒。

也许我们甚至可以对数据库本身进行一些调整?我们使用SQL Compact Database。

4 个答案:

答案 0 :(得分:2)

如果优化器相当聪明,并且特别是如果将ChangeDate列编入索引,那么使用Take(2)确实会有所作为。 (我不知道SQL Compact版本有多少优化,但我仍然希望限制结果有用。)

但是,你不应该相信我或其他任何人这么说。查看每种情况下生成的查询,并针对SQL事件探查器运行它。了解执行计划是什么。使用各种样品测量性能。测量,测量,测量。

答案 1 :(得分:1)

您可能遇到的问题是数据被下拉到您的计算机,然后您正在执行Take(2)。可能花费最多时间的部分是将所有数据提取到您的应用程序。如果您希望SQL Server执行此操作,请确保在完成查询语句之前不访问任何结果集记录的值。

其次,LINQ对于排序和应用程序内存中大量数据的子句的处理速度并不快。有时在LINQ中编写要容易得多,但在数据库中执行尽可能多的排序和where子句总是更好,而不是在内存对象集中进行操作。

如果您真的关心此方案中的性能,请不要使用LINQ。只需制作一个循环。

http://ox.no/posts/linq-vs-loop-a-performance-test

我喜欢使用LINQ-To-SQL和LINQ,但它并不总是适合这项工作的工具。如果您有大量数据并且性能至关重要,那么您不希望在内存排序和where语句中使用LINQ。

答案 2 :(得分:0)

添加.Take(2)会产生很大的不同。如果你只需要两件物品,那么你一定要使用它,这肯定会给你带来性能差异。

添加它并查看从中生成的SQL。生成的SQL只能获得2条记录,这样可以节省SQL时间和对象实例化方面的时间。

答案 3 :(得分:0)

1 - 添加索引以涵盖您在查询中使用的字段

2 - 确保过于频繁地重复查询不能获得前2名

  • 尝试定义可让您拍摄一批记录的查询条件

3 - 尝试编译LINQ查询