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

发布于 2024-10-26 21:27:00 字数 450 浏览 1 评论 0原文

查询 1:(快如闪电)

sp_executesql "select * from tablesView where Id = 1"

查询 2:(太慢)

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

tablesView - 包含多个联接的视图

LINQ 始终将查询转换为 Query2 形式,因此性能非常糟糕。

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

----附加评论:

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

Query 1: (lightning fast)

sp_executesql "select * from tablesView where Id = 1"

vs.

Query 2: (too slow)

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

tablesView - a view containing multiple joins

LINQ always converts queries to Query2 form and hence the performance is really bad.

Questions: I need reason for query2 slowness, and any resolution if there's one.
And a resolution for LINQ.

----Additional comments:

The performance hit is definitely because of the 2 columns which are using ranking functions(row_number) but I can't avoid them I need them.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

野心澎湃 2024-11-02 21:27:00

我将在这里冒险并假设您有很多 ID = 1 的行。

如果不是,请纠正我。

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

嗯,我想知道他会为该参数传递什么。
会是1吗?我在哪里有无数行?
或者也许是 1742 年,我只有 3
我只是不知道,我最好进行一次表扫描,以确保生成一个涵盖我所有基础的执行计划

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

至少这是我的经验。特别是,在对具有时间限制的数据的表进行日期范围选择时,我看到了相同的行为,执行 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

I'm going to go out on a limb here and assume that you have a lot of rows where ID = 1.

If not, please correct me.

One possible reason that SQL Server is processing your query slow is that it looks at the query and goes:

hmm, I wonder what he's going to pass for that parameter.
is it going to be 1? where I have about a gazillion rows?
or perhaps 1742, where I have just 3
I just don't know, I better do a table scan to be sure to produce an execution plan that will cover all my bases

If a column, or a column set, has low selectivity (ie. the number of unique values is far less than the number of rows), SQL Server will sometimes revert to a tablescan or similar, just to get all rows deterministically.

At least that's been my experience. In particular I've seen the same behavior when doing date range selects on tables with time-bound data, doing a WHERE dt <= @dt AND dt >= @dt to get all rows where @dt is inside a period of time in that row, reverts to a table-scan, and then when I place the actual date into the SQL as a literal it runs far faster.

The problem here is the selectivity, SQL Server doesn't know how to best cater for all scenarios when building an execution plan for your statement, so it'll try to guess.

Try adding a query hint to specify a typical value for the parameter, ie.:

sp_executesql "select * from tablesView where Id = @Id option (optimize for (@id = 1742))", N"@Id int", @Id=1
一世旳自豪 2024-11-02 21:27:00

这可能是一个参数嗅探问题。 添加以下行:

OPTION (RECOMPILE)

尝试在 SQL 查询末尾

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

This could be a parameter sniffing problem. Try including the line:

OPTION (RECOMPILE)

at the end of your SQL query.

There is an article here explaining what parameter sniffing is: http://blogs.technet.com/b/mdegre/archive/2012/03/19/what-is-parameter-sniffing.aspx

ゞ记忆︶ㄣ 2024-11-02 21:27:00
  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)
  1. Avoid using SELECT *
  2. ADO.NET 3.5 there is "parameter quessing" in Linq 1=TINYINT 2345=SMALLINT 76357242=INT ..
    in ADO.NET 4.0 parameter quessing is replaced with default INT data type 1=INT, 2335=INT ,76357242=INT)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文