总之,我有一个从 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
.