【问题标题】:Comparing 2 linq applications: Unexpected result比较 2 个 linq 应用程序:意外结果
【发布时间】:2010-05-16 11:21:19
【问题描述】:

我使用 LINQ 起草了 2 个 ASP.NET 应用程序。一个连接到MS SQL Server,另一个连接到一些专有内存结构。 这两个应用程序都使用 3 个 int 字段 的表,具有 500 000 条记录(内存结构与 SQL Server 表相同)。使用的控件是常规的:GridViewObjectDataSource。 在应用程序中,我计算每次分页点击处理所需的平均时间。

  • LINQ + MS SQL 应用程序要求每次页面更改 0.1 秒
  • LINQ + 内存结构要求每页更改 0.8 秒。

这是令人震惊的结果。为什么在内存中处理数据的应用程序的运行速度比使用硬盘驱动器的应用程序慢 8 倍?谁能告诉我为什么会这样?

【问题讨论】:

  • 您能发布您的查询吗?

标签: asp.net sql-server linq objectdatasource


【解决方案1】:

主要因素可能是算法效率。 LINQ-to-Objects 与IEnumerable<T> 输入和输出一起工作,这些输入和输出通常是按顺序处理的,而数据库可能有索引会导致显着加速。

【讨论】:

    【解决方案2】:

    我能想到至少三个原因:

    • 索引
    • 缓存
    • 特殊优化(例如 TOP N SORT)

    索引

    如果在正确索引的数据库上运行,许多类型的查询运行速度会非常快,但如果您在内存中遍历列表,则运行速度会非常慢。例如,在数据库中按 ID(主键)查找几乎是即时的,因为结果存储在高度非常小的 B 树中。要在内存中的列表中找到相同的元素,需要扫描整个列表。

    缓存

    您的假设是数据库总是命中磁盘。这并非总是如此。数据库将尝试在内存中保存尽可能多的数据,因此当您向它询问数据时,它已经为您准备好了答案。特别是它会在内存中保存常用的索引,并且只在必要时访问磁盘。数据在磁盘和内存中的存储方式也经过精心优化,以减少磁盘寻道和页面缺失。

    优化

    即使没有索引,数据库仍然知道许多可以加快处理速度的技巧。例如,如果您在 SQL Server 中执行以下操作:

    list.OrderBy(x => x.Value).Take(1)
    

    如果列表上有索引,它几乎是即时的,但即使没有索引,它也会使用称为TOP N SORT 的特殊优化,该优化以线性时间运行。检查查询的执行计划以查看是否正在使用此优化。请注意,此优化并未针对 LINQ to Objects 实现。我们可以通过运行这段代码看到这一点:

    Random random = new Random();
    List<Foo> list = new List<Foo>();
    for (int i = 0; i < 10000000; ++i)
    {
        list.Add(new Foo { Id = random.Next() });
    }
    
    DateTime now = DateTime.UtcNow;
    Foo smallest = list.OrderBy(foo => foo.Id).First();
    Console.WriteLine(DateTime.UtcNow - now);
    

    这段代码需要大约 30 秒的时间来执行,并且随着项目的添加,执行时间比线性增长要慢。用这个替换查询会花费不到一秒钟的时间:

    int smallestId = list.Min(foo => foo.Id);
    

    这是因为在 LINQ to objects 中 OrderBy 是使用 O(n log(n)) 算法实现的,但 Min 使用 O(n) 算法。但是,当针对 SQL Server 执行时,这两个查询都会产生相同的 SQL,并且都是线性时间 - O(n)

    因此,在数据库中运行像OrderBy(x =&gt; x.Something).Skip(50).Take(10) 这样的分页查询会更快,因为我们付出了更多努力来确保它更快。毕竟,这种查询的速度是数据库的一大卖点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多