我有一个通过LINQ to SQL执行的查询。查询如下所示:
exec sp_executesql N'
SELECT DISTINCT [t2].[ID],...
FROM
Table1 AS [t0]
INNER JOIN Table2 AS [t1] ON [t0].[Table1ID] = [t1].[Table1ID]
INNER JOIN Table3 AS [t2] ON [t2].[Table2ID] = [t0].[Table2ID]
WHERE
([t2].[Visible] = @p0)
AND ([t1].[AncestorID] IN (@p1,...,@p277))',N'@p0 int,...,@p277 int',@p0=1,...@p277=2875
正如您所看到的,它基本上是一个带有277个参数的子句查询。使用exec并传递上述参数,查询需要 20秒。
如果我将查询从exec调用中拉出并“正常”运行,则需要的时间少于一秒。这是查询:
DECLARE @p0 int;
...
DECLARE @p277 int;
SET @p0=1;
...
SET @p277=287;
SELECT DISTINCT [t2].[ID],...
FROM
Table1 AS [t0]
INNER JOIN Table2 AS [t1] ON [t0].[Table1ID] = [t1].[Table1ID]
INNER JOIN Table3 AS [t2] ON [t2].[Table2ID] = [t0].[Table2ID]
WHERE
([t2].[Visible] = @p0)
AND ([t1].[AncestorID] IN (@p1,...,@p277))
第三个测试,当我在exec中包装第二个查询时,立即工作。所以问题似乎是在exec调用中传递参数。
答案 0 :(得分:1)
所以问题似乎与之相关 传递参数 执行电话。
我认为你出于某种原因有不同的执行计划。
这是Erland Sommarskog的一篇文章,可以帮助你弄清楚发生了什么。
Slow in the Application, Fast in SSMS? Understanding Performance Mysteries
答案 1 :(得分:0)
这个问题可能与“参数嗅探”有关,@Mikael链接的文章谈到了这一点。不幸的是,这是使用ORM的主要缺点之一,因为你失去了调整SQL性能的能力。
以下是一些尝试:
此外,您的第二次和第三次测试基本上与Ad Hoc查询相同,其计划使用基于查询的EXACT文本的密钥进行缓存,包括空格等。因此将其包装在EXEC中确实不应该更改优化器如何看待它。