直接SQL查询与EXEC

时间:2011-04-15 18:25:33

标签: sql-server linq-to-sql

我有一个通过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调用中传递参数。

2 个答案:

答案 0 :(得分:1)

  

所以问题似乎与之相关   传递参数   执行电话。

我认为你出于某种原因有不同的执行计划。

这是Erland Sommarskog的一篇文章,可以帮助你弄清楚发生了什么。

Slow in the Application, Fast in SSMS? Understanding Performance Mysteries

答案 1 :(得分:0)

这个问题可能与“参数嗅探”有关,@Mikael链接的文章谈到了这一点。不幸的是,这是使用ORM的主要缺点之一,因为你失去了调整SQL性能的能力。

以下是一些尝试:

  1. 运行DBCC FREEPROCCACHE并运行 来自应用程序的查询再次查看 如果这有任何区别。运行 它多次不会得到一个新的 执行计划,因为它已经存在 从第一次运行缓存。
  2. 请务必重建索引 表格以确保 统计数据是最新的(a 重建,而不是碎片整理应该 自动更新统计数据)
  3. 如果需要,您可以随时转换它 对存储过程的操作和调用 从LINQ-to-SQL。那你就可能了 必须以逗号形式传递值列表 分隔列表或XML。如果您使用的是SQL Server 2008(或更新)最好的解决方案是 在app端构造一个DataTable并传递 作为表值参数进入Proc 并在INNER JOIN而不是IN列表中使用它。
  4. 此外,您的第二次和第三次测试基本上与Ad Hoc查询相同,其计划使用基于查询的EXACT文本的密钥进行缓存,包括空格等。因此将其包装在EXEC中确实不应该更改优化器如何看待它。