【问题标题】:Stored Procedure slower than LINQ query?存储过程比 LINQ 查询慢?
【发布时间】:2016-01-23 15:51:42
【问题描述】:

我正在做一些测试,直接 LINQ-to-SQL 查询的运行速度至少比通过 LINQ 查询调用存储过程快 80%

在 SQL Server 分析器中,一个通用的 LINQ 查询

 var results = from m in _dataContext.Members
 select m;

与存储过程相比,只用了 19 毫秒

 var results = from m in _dataContext.GetMember(userName)
 select m;

GetMember 是存储过程)执行相同的查询需要 100 毫秒

这是为什么?

编辑:

在 Profiler 中直接的 LINQ 看起来像这样

SELECT 
    [t1].[MemberID], [t1].[Aspnetusername], [t1].[Aspnetpassword], 
    [t1].[EmailAddr], [t1].[DateCreated], 
    [t1].[Location], [t1].[DaimokuGoal], [t1].[PreviewImageID],   
    [t1].[value] AS [LastDaimoku], 
    [t1].[value2] AS [LastNotefied], 
    [t1].[value3] AS [LastActivityDate], [t1].[IsActivated]
FROM 
    (SELECT 
         [t0].[MemberID], [t0].[Aspnetusername], [t0].[Aspnetpassword], 
         [t0].[EmailAddr], [t0].[DateCreated], [t0].[Location], 
         [t0].[DaimokuGoal], [t0].[PreviewImageID], 
         [t0].[LastDaimoku] AS [value], [t0].[LastNotefied] AS [value2], 
         [t0].[LastActivityDate] AS [value3], [t0].[IsActivated]
     FROM 
         [dbo].[Members] AS [t0]) AS [t1]
WHERE 
    [t1].[EmailAddr] = @p0

存储过程是这样的

SELECT Members.*
FROM Members 
WHERE dbo.Members.EmailAddr = @Username

所以您看到存储过程查询要简单得多.. 但速度较慢.. 对我来说毫无意义。

【问题讨论】:

  • 看起来你的两个查询做的不一样。第二个接受一个参数(大概是为了限制结果),第一个显然只是获取所有行。对于初学者,你确定 SQL 是一样的吗?
  • 存储过程中的 sql 与他们 linq 查询所做的相同......基本上你是正确的参数......通过 linq 查询返回所有行比返回单个更快存储过程中的行。

标签: linq-to-sql stored-procedures


【解决方案1】:

1) 比较同类。在两种情况下执行完全相同的操作,而不是在一种情况下获取所有值并在另一种情况下进行查询。

2) 不要只执行一次代码 - 多次执行,这样优化器就有机会工作并避免一次性的性能损失。

3) 使用分析器(嗯,一个在 .NET 端,一个在 SQL 端)找出性能实际上不同的地方。

【讨论】:

    【解决方案2】:

    可能会使其变慢的一件事是 select *.通常,如果指定了列,查询会更快,特别是如果 LINQ 查询没有使用查询中所有可能的列,它会比 select * 更快。

    【讨论】:

      【解决方案3】:

      我忘了,proc 也可能有参数嗅探问题。

      【讨论】:

        【解决方案4】:

        在 cmets 中指出,其中一些是您没有将苹果与苹果进行比较。您正在尝试比较两个不同的查询,从而得到不同的结果。

        如果您想尝试确定性能,您需要比较相同的查询、相同的值等。

        此外,您可以尝试使用 LinqPad 来查看生成的 SQL 以识别可能导致响应缓慢的区域。

        【讨论】:

          【解决方案5】:

          * 将延长运行查询所需的时间。此外,您在分析器中看到的来自 LINQ 的直接 SQL 将所有对象名称括起来 ([]) - 这将减少 LINQ 查询的查询执行时间。

          【讨论】:

            【解决方案6】:

            我可以补充一下 John Skeet 的回答,当多次运行代码时,请记住清理所有查询缓存。

            我可以建议对这两个查询都使用“EXPLAIN”:似乎 MySQL 为查询和 SP 创建查询执行计划的方式不同。对于 SP,它在用它们的值替换参数之前符合要求,因此它不使用在硬编码或替换参数的情况下使用的索引。这是来自 SO 的another question about different run times for SP and straight query,其中提供了两种情况的查询计划数据。

            【讨论】:

              猜你喜欢
              • 2015-02-23
              • 1970-01-01
              • 1970-01-01
              • 2013-12-07
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多