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

Who*_*nja 10 .net sql linq sql-server

查询1 :(闪电般快)

sp_executesql "select * from tablesView where Id = 1"
Run Code Online (Sandbox Code Playgroud)

查询2 :(太慢)

sp_executesql "select * from tablesView where Id = @Id", N"@Id int", @Id=1
Run Code Online (Sandbox Code Playgroud)

tablesView - a view containing multiple joins

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

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

- - 附加评论:

性能打击肯定是因为2列使用排名函数(row_number)但我无法避免它们我需要它们.

ang*_*son 7

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

如果没有,请纠正我.

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

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

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

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

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

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

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


小智 0

  1. 避免使用 SELECT *
  2. ADO.NET 3.5 Linq 1=TINYINT 2345=SMALLINT 76357242=INT 中存在“参数查询”。在 ADO.NET 4.0 中,参数查询被替换为默认 INT 数据类型 1=INT、2335=INT ,76357242=INT)