所有,我有一个动态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
针对不同的数据库。
答案 0 :(得分:0)
当你做RECOMPILE时,sql server每次都会生成新的执行计划并执行它。另外,它将尝试使用存储在过程高速缓存中的现有执行计划,这对于当前查询可能是错误的,因为在动态查询中,条件和参数在每次执行时都会更改。