2011-03-25 118 views
10

查询1:(快如闪电)为什么sp_executesql的参数时作为参数传递运行速度较慢

sp_executesql "select * from tablesView where Id = 1" 

问题2:(太慢)

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

tablesView - a view containing multiple joins

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

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

----附加注释:

对性能的影响肯定是因为2列,其使用排名函数(ROW_NUMBER),但我不能避免他们我需要他们。

+0

你有很多与ID = 1的行? – 2011-03-25 21:07:16

+0

@Lasse,即使我有50条记录,差异是巨大的。比如0秒和10秒,有一点是select * from table,通常是一个有很多连接的视图。 – WhoIsNinja 2011-03-25 21:08:43

+0

“@ id”传入的数据类型是什么?您可能会进行隐式转换以防止使用索引。 – 2011-03-25 21:09:17

回答

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

我从不使用select *,这仅仅是一个例子。 – WhoIsNinja 2011-03-25 21:22:58

7

我要去这里走出去的肢体,并假定你有很多行的其中ID = 1

如果没有,请纠正我。

一个可能的原因是SQL Server正在处理您的查询速度慢是,它看起来在查询和云:

嗯,我不知道他会通过该参数。
它会是1吗?在那里我有关于gazillion行?
或者是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 
+0

优化并没有帮助,但我不能要求linq在其构建的查询中添加优化。 :( – WhoIsNinja 2011-03-25 21:31:20

+0

说到记录,如果在这个查询中没有where子句,将会有100万条记录被返回,因为这个视图包含巨大的表之间的连接 – WhoIsNinja 2011-03-25 21:34:02

+1

1.谁对“没有where子句”和“尝试使用optimize for子句执行SQL并查看差异?3)...是不知道数据仍然是最佳方法的ORM? – 2011-03-25 21:41:36

2

这可能是一个参数嗅探问题。尝试包括线路:

OPTION (RECOMPILE) 

在您的SQL查询的结尾。

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

+0

尽管我不能直接使用它,但它是我的问题的答案,即参数导致表扫描而不是使用索引。使用OPTION(RECOMPILE)确实强制底层视图使用使用表索引的计划。不幸的是我无法使用这个,因为我的SQL中间件解析器不能接受这个语法。我的解决方法是构建不带参数的SQL,有效地将值编码到查询中。没有理想,但它避免了将查询转换为sp_executesql。 – Paul 2015-04-02 09:49:53