0

動的な SQL があります。実行には約 4 分かかります。代わりに静的 SQL にすると、約 20 秒かかります。

ほとんどの場合、2 つのクエリは次のとおりです。

@myVar = 1
SELECT *
FROM TABLE
WHERE someColumn = myVar

対:

@myQuery = '
SELECT *
FROM TABLE
WHERE someColumn = myVar'

EXEC sp_executesql @myQuery,
    N'@myVar INT,
    @myVar

私の実際のクエリははるかに複雑です。10x統計を見ると、動的なものは読み取り数よりも多くなっています。これを修正するために、このクエリを静的にしたいと考えています。ただし、動的である理由は、挿入と選択が変数を使用して行われるためです。

私は次のようなものを持っています:

@someVar1 = "column1, column2, column3"
@someVar2 = "column4, column5, column6"

そして、

@myQuery = 'INSERT INTO '+ @someVar1 + 
           'SELECT ' + @someVar2 + ' FROM ....'

次のようなことをする方法はありますか:

INSERT INTO @myVar1
SELECT @myVar2
FROM
...

このクエリを修正する他の方法がわかりません。修正がどうしても必要です。

編集いくつかの変更を加えました。動的なものも挿入ステートメントに含まれていることを忘れていました。起きてから投稿するとこうなります。

4

1 に答える 1

1

あなたはユニコーンを追いかけています。SQL Serverでは、非動的クエリで置換@varすることはできません。column1, column2構文は、あなたがやりたいことをサポートしていません (とにかく状況を改善するわけではありません)。

したがって、この「問題」を他の方法で解決する必要があります。同じクエリの動的バージョンが読み取りで 10 倍の変位をもたらすとは信じがたいことです。これが事実である場合 (効果を誇張しているのではなく、証拠を示してください)、ほぼ確実に、キャッシュされた (静的) クエリが 1 つのプラン形状につながるパラメーターを使用したパラメーター スニッフィングが原因であり、そのプランshape は、異なるクエリ テキストまたは異なるパラメーター、またはその両方を持つ他の (動的) クエリには最適ではありません。実行時に強制し、クエリテキストが毎回同じであることを確認することで、ある程度これを打ち消すことができRECOMPILEます (これには、空白、大文字化などが含まれます)。

SET @myQuery = N'INSERT dbo.DestinationTable(' 
  + @DestinationColumns + ')
  SELECT ' + @SourceColumns + '
  FROM dbo.SourceTable
  WHERE someColumn = @myVar OPTION (RECOMPILE);';

しかし、それがあなたの問題であるとは確信していません。実際の観察よりも知覚/恐怖かもしれないと思います。

コメントで述べたように、多数の異なる動的 SQL ステートメントを作成している場合は、この設定をオンにすることを検討する必要optimize for ad hoc workloadsがあります。これにより、二度と使用しないプランでプラン キャッシュが肥大化するのを防ぐことができます。

無料版のSQL Sentry Plan Explorerを使用すると、約 0.5 秒で非常に簡単に計画を難読化できます。また、私たちが確認できる場所にアップロードすることもできます。これでは、実際のクエリ テキストを分析することはできませんが、クエリ自体の計画に違いがあることがわかります。これは、クエリが動的に構築されたかどうかに関係なく、単に異なるだけです。免責事項: 私は SQL Sentry で働いています。

于 2013-03-28T14:33:59.643 に答える