奇怪的C#到SQL动态查询执行

时间:2012-09-25 10:20:51

标签: c# sql sql-server-2008 dynamic-sql

所有,我有一个动态SQL查询,我正在从C#应用程序执行。问题查询是一个INSERT语句,它从C#循环中运行,在许多数据库上按顺序执行以创建单个数据仓库[数据库]。我已经在一个批次中运行此代码一个100多个数据库而没有问题;但是,我刚遇到一个查询

的特定数据库
DECLARE @DbName NVARCHAR(128);
SET @DbName = (SELECT TOP 1 [DbName] 
               FROM [IPACostAdmin]..[TmpSpecialOptions]);
DECLARE @FilterSql NVARCHAR(MAX);
SET @FilterSql = (SELECT TOP 1 [AdditionalSQL] 
                  FROM [IPACostAdmin]..[TmpSpecialOptions]);
DECLARE @SQL NVARCHAR(MAX);
DECLARE @SQL1 NVARCHAR(MAX);
DECLARE @SQL2 NVARCHAR(MAX);
SET @SQL1 = 
'INSERT INTO [' + @DbName + ']..[Episode] WITH(TABLOCK) 
    ([EstabID],..., [InclFlag]) '; 
SET @SQL2 = 
'SELECT 
     [EstabID],..., [InclFlag] 
FROM [B1A] ' + @FilterSql + ';'; 
SET @SQL = @SQL1 + @SQL2;
EXEC sp_executesql @SQL;

从大约三秒钟开始插入20,000-30,000条记录到40多分钟!现在,经过长时间的考虑和实验,我刚刚解决了这个问题;这是使用

EXEC sp_executesql @SQL WITH RECOMPILE; 

这使它回归到<插入2s。

这个SQL是从应用程序为批处理中的每个数据库执行一次的,就服务器而言,此语句的当前执行应完全独立于前面的那些(据我所知)它),但它不是;在这种情况下,似乎SQL正在兑现动态SQL。

我想知道这个单一网站发生了什么?我将在哪里确保将来使用RECOMPILE选项来防止此类问题?

感谢您的时间。

_注意。我很欣赏这会重新编译查询,但我对于为什么服务器首先使用相同的执行计划感到困惑。每次运行此查询时,它都使用不同的Initial Catalog使用不同的SqlConnection针对不同的数据库。

1 个答案:

答案 0 :(得分:0)

当你做RECOMPILE时,sql server每次都会生成新的执行计划并执行它。另外,它将尝试使用存储在过程高速缓存中的现有执行计划,这对于当前查询可能是错误的,因为在动态查询中,条件和参数在每次执行时都会更改。