当参数作为参数传递时,为什么sp_executesql运行速度较慢

时间:2011-03-25 21:04:04

标签: .net sql sql-server linq

查询1 :(闪电般快速)

sp_executesql "select * from tablesView where Id = 1"

VS

查询2 :(太慢)

sp_executesql "select * from tablesView where Id = @Id", N"@Id int", @Id=1

tablesView - a view containing multiple joins

LINQ总是将查询转换为Query2格式,因此性能非常糟糕。

问题:我需要查询2缓慢的原因,以及任何解决方案(如果有的话)。 LINQ的解决方案。

----补充评论:

性能命中肯定是因为使用排名函数的两列(row_number)但我无法避免它们我需要它们。

3 个答案:

答案 0 :(得分:7)

我将在这里走出困境并假设你有很多行,ID = 1。

如果没有,请纠正我。

SQL Server处理查询的一个可能原因是查看查询并执行:

  嗯,我想知道他将为这个参数传递什么   它会是1吗?我在哪里有大量的行?
  或者也许是1742年,我只有3岁   我只是不知道,我最好做一个表扫描,以确保制定一个涵盖我所有基地的执行计划

如果列或列集具有低选择性(即唯一值的数量远小于行数),SQL Server有时会恢复为表扫描或类似,只是为了确定性地获取所有行

至少那是我的经历。特别是我在日期范围选择具有时间限制数据的表时看到了相同的行为,执行WHERE dt <= @dt AND dt >= @dt以获取@dt在该行的一段时间内的所有行,恢复为表-scan,然后当我将实际日期作为文字放入SQL时,它运行得更快。

这里的问题是选择性,SQL Server不知道在为语句构建执行计划时如何最好地满足所有场景,所以它会尝试猜测。

尝试添加查询提示以指定参数的典型值,即:

sp_executesql "select * from tablesView where Id = @Id option (optimize for (@id = 1742))", N"@Id int", @Id=1

答案 1 :(得分:2)

这可能是参数嗅探问题。尝试包括以下行:

OPTION (RECOMPILE)

在SQL查询结束时。

这里有一篇文章解释了什么参数嗅探:http://blogs.technet.com/b/mdegre/archive/2012/03/19/what-is-parameter-sniffing.aspx

答案 2 :(得分:0)

  1. 避免使用SELECT *
  2. ADO.NET 3.5 Linq 1中有“参数调整”= TINYINT 2345 = SMALLINT 76357242 = INT .. 在ADO.NET 4.0中,参数quessing将替换为默认的INT数据类型1 = INT,2335 = INT,76357242 = INT)