すべて、C# アプリケーションから実行している動的 SQL クエリがあります。問題のクエリは、C# ループ内から実行される INSERT ステートメントであり、単一のデータ ウェアハウス [データベース] を作成するために多数のデータベースで順次実行されます。このコードを 100 以上のデータベースで 1 回のバッチで問題なく実行しました。ただし、クエリが存在する特定のデータベースに出くわしました
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 は、アプリケーションからバッチ内の各データベースに対して 1 回実行されます。このステートメントの現在の実行は、サーバーに関する限り (私が理解しているように)、前のステートメントとは完全に分離されている必要がありますが、そうではありません。この場合、SQL は動的 SQL をキャッシュしているようです。
この単一のサイトで何が起こっているのか知りたいですか? RECOMPILE
このような問題を防ぐために、将来このオプションを使用することを確認する必要があるのはどこですか?
御時間ありがとうございます。
_ノート。これによりクエリが再コンパイルされることには感謝していますが、そもそもサーバーが同じ実行プランを使用している理由について困惑しています。このクエリが実行されるたびに、別のを使用して別Initial Catalog
の を使用して別のデータベースに対して行われますSqlConnection
。