为什么当参数作为参数传递时 sp_executesql 运行速度变慢
查询 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我将在这里冒险并假设您有很多 ID = 1 的行。
如果不是,请纠正我。
SQL Server 处理查询速度缓慢的一个可能原因是它查看查询并执行以下操作:
如果列或列集的选择性较低(即唯一值的数量要少得多)比行数),SQL Server 有时会恢复到表扫描或类似的操作,只是为了确定性地获取所有行。
至少这是我的经验。特别是,在对具有时间限制的数据的表进行日期范围选择时,我看到了相同的行为,执行
WHERE dt <= @dt AND dt >= @dt
来获取所有行@dt 位于该行的一段时间内,恢复为表扫描,然后当我将实际日期作为文字放入 SQL 中时,它运行得更快。这里的问题是选择性,SQL Server 在为语句构建执行计划时不知道如何最好地满足所有场景,因此它会尝试猜测。
尝试添加查询提示来指定参数的典型值,即:
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:
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.:
这可能是一个参数嗅探问题。 添加以下行:
尝试在 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:
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
在 ADO.NET 4.0 中,参数查询被替换为默认的 INT 数据类型 1=INT, 2335=INT ,76357242=INT)
in ADO.NET 4.0 parameter quessing is replaced with default INT data type 1=INT, 2335=INT ,76357242=INT)