【问题标题】:Why would LINQ to SQL perform better than a straight SQL query?为什么 LINQ to SQL 比直接 SQL 查询执行得更好?
【发布时间】:2008-10-21 05:05:26
【问题描述】:

奇怪的性能结果,我有一个 LINQ to SQL 查询,它使用几个 let 语句来获取看起来像这样的各种信息

    public IQueryable<SystemNews> GetSystemNews()
{
    using (var t = new TransactionScope(TransactionScopeOption.Required,
              new TransactionOptions { IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted }))
    {
        var results = from s in _datacontext.SystemNews
                      let member = GetMemberInfo(s.MemberID)
                      let determination = GetDetermination(s.DeterminationID.Value)
                      let daimoku = GetDaimoku(s.DaimokuID.Value)
                      let entry = GetEntry(s.EntryID.Value)
                      let encouragment = GetEncouragement(s.EncouragementID.Value)
                      select new SystemNews
                      {
                          NewsDate = s.NewsDate,
                          MemberID = s.MemberID,
                          PhotoID = s.PhotoID.Value,
                          DeterminationID = s.DeterminationID.Value,
                          DaimokuID = s.DaimokuID.Value,
                          EntryID = s.EntryID.Value,
                          EncouragementID = s.EncouragementID.Value,
                          Member = new LazyList<Members>(member),
                          Determination = new LazyList<Determinations>(determination),
                          Daimoku = new LazyList<MemberDaimoku>(daimoku),
                          Entry = new LazyList<MemberEntries>(entry),
                          Encouragement = new LazyList<MemberEncouragements>(encouragment),
                          IsDeterminationComplete = s.IsDeterminationComplete.Value
                      };
        return results;
    }
}

我在 SQL 视图中创建了相同的东西(基本上至少是在此获得的各种信息),并且 LINQ to SQL 在 90 毫秒内返回结果,而视图返回相同的数据实际上在过去的信息更少700 毫秒。谁能解释一下?

【问题讨论】:

    标签: .net sql-server linq-to-sql


    【解决方案1】:

    一般来说,LINQ-to-SQL 将“大致相同”,我同意缓存在这里可能是一个问题。确实需要查看生成的 SQL;最简单的方法是:

    _datacontext.Log = Console.Out;
    

    然后尝试直接在查询分析器中运行 TSQL。 SPROC 在能够优化访问、使用表变量等方面有一些优势;但是,LINQ 具有可组合性的优势——即您可以在单个查询中应用分页、排序、投影等。您可以一推使用 SPROC 做到这一点,但这是非常艰苦的工作。

    但实际上,关键在于查看 TSQL;可能是您没有加载所有数据,例如(延迟加载)。

    【讨论】:

    • 就查询而言,L2S 不做任何缓存。
    • @usr - 您可以使用预编译查询,数据库将自动使用缓存的查询计划 any 参数化查询(预编译与否)。身份管理器还缩短了主键查找以避免数据库命中。 IMO 远非如此……
    • 你的说法是真的,我没有想到那些。但是我相信你提到的效果在这里不起作用。
    【解决方案2】:

    您是否使用过 SQL 分析器来检查 LINQ 生成的 SQL 与您用来比较的 SQL 之间的差异?

    也许 LINQ to SQL 查询得到了更好的优化?

    【讨论】:

    • 是的,我就是这样知道哪个表现更好。
    【解决方案3】:

    您可能会看到缓存效果;这不是真的。

    基准测试的一个原则是,您可以通过运行基准测试一次,在缓存中获取结果,然后再次运行它并报告惊人的结果,或者相反的方式来调整您的基准测试......

    【讨论】:

      【解决方案4】:

      粗略一看,您的 Linq to SQL 查询似乎正在使用延迟加载。如果我是对的,那么运行您的查询实际上不会在那时运行查询的所有部分是有道理的。这意味着,如果您将其与设置为一次性恢复所有这些结果的 SQL 视图进行比较,那么肯定会做更多的工作,因此需要额外的时间。

      另外两点:

      1. 确保您正在计时实际查询执行而不是查询表达式的分配。请记住,Linq 查询是延迟的,因此当您从上述方法返回查询时,它实际上是返回表达式而不是结果。通常,执行 Linq 查询的三种流行方法是运行 ToArray 或 ToList 扩展方法,或者简单地使用 foreach 迭代结果。

      2. 1234563与使用 Linq to SQL 多次查询的窄片段相比。

      我从来没有对此进行过任何基准测试来查看临界点在哪里,但您可以想象一下,您有两个表 Table1 和 Table2,每个表都有 100 列,Table1 中也有 1,000 行数据与 Table2 的一对多关系,通常在 Table2 中为 Table1 中的每条记录产生 10 个匹配项。现在,如果您编写一个视图以将所有这些结果拉回单个查询中,您将期望大约 10,000 行数据,所有数据大约 200 列宽。通过发出两个单独的查询,但是通过 Linq to SQL 或任何其他机制,您可以改为从 Table1 获取初始 1,000 行 100 列宽的结果,然后选择剩余的 Table2 项目,可能是另外 100 列的 10,000 行,总共 1,100,000 个单元格(这比 SQL 视图中的 2,000,000 个单元格要少得多)。如果我们假设多对多关系的依赖行之间有很大程度的重叠,那么好处会更加夸张。在最极端的情况下,存在 100% 的重叠,这意味着我们只期望总共拉回 100,010 个数据单元,这远远少于平面视图返回的 2,000,000 个。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多