1

总之,我有一个从 C# 应用程序执行的动态 SQL 查询。问题查询是一个 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 条记录大约需要 3 秒到 40 多分钟!现在,经过长时间的考虑和实验,我刚刚解决了这个问题;它是使用

EXEC sp_executesql @SQL WITH RECOMPILE; 

这使其插入时间回落到 < 2 秒。

对于批处理中的每个数据库,此SQL从应用程序执行一次,就服务器而言,该语句的当前执行应该与前面的执行完全分开(据我了解),但事实并非如此;在这种情况下,似乎 SQL 正在兑现动态 SQL。

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

谢谢你的时间。

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

4

1 回答 1

0

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

于 2012-09-25T10:30:56.697 回答