2017-12-20 3 views
1

以下のような、私がリモートサーバーに対して実行している例を考えてみましょう。コマンド自体はデータを返しませんが、プロセスエクスプローラでプロセスを見ると、ネットワーク上で大量のデータを受信して​​いることがわかります。以下の例では370MBを受信しました。 DBサーバー上でプロセスエクスプローラを見る私は、クライアントマシン上のネットワークアクティビティグラフと完全に一致するネットワークアクティビティグラフを見ることができますが、これは送信データ用です。100秒のネットワークトラフィックを生成するデータを返さないSQLコマンドが長時間実行されているのはなぜですか?

これを引き起こしている原因は何ですか。どのように防止できますか?

var query = @" 
    declare @Value nvarchar(max), @index int 
    set @index = 0 

    while @index < 10000000 
    begin 
     set @Value = 'this is just a test' 
     set @index = @index + 1 
    end"; 

var connectionString = "MyConnectionString"; 

using (var connection = new SqlConnection(connectionString)) 
using (var command = connection.CreateCommand()) 
{ 
    connection.Open(); 

    command.CommandTimeout = 0; 
    command.CommandText = query; 
    command.ExecuteNonQuery(); 
} 
+0

イベントハンドラを 'SqlConnection.InfoMessage'イベントにフックして、サーバからのイベントでスパムを受けているかどうかを確認してください。 –

+0

@LasseVågsætherKarlsenイベントは発生しません。 –

+1

@JasonBoydクエリの最初のステートメントとして 'SET NOCOUNT ON;'をスローすると、使用量が減少しますか? –

答えて

3

SQLは、バッチ内の各SQL文に対してDONE tokenと応答します。各トークンは13バイトです。

ループの各繰り返しは、3つのステートメント(2つのセットステートメントとループ条件付き構造体自体)を表します。 3 * 13バイト* 10,000,000 = 390 MB。

SET NOCOUNT ON(ありがとう、Scott)を使用してこれを回避できます。

+0

ストアドプロシージャではDONEの代わりに[DONEINPROC](https://msdn.microsoft.com/en-us/library/dd340553.aspx)を取得するだけです。 –

+1

クエリの最初の文として 'SET NOCOUNT ON;'を設定すると、DONEトークンとDONEINPROCトークンが表示されないように問題を解決するはずです。 –

+0

これが_quite_であるかわからない、または間違っています。 'SET NOCOUNT ON'を単に追加するだけでは動作が変更されません。全体をストアドプロシージャとしてラップしても、動作は変わりませんでした。しかし、ストアドプロシージャとして全体をラップし、 'SET NOCOUNT ON'をストアドプロシージャに追加すると、ほとんどの場合、ネットワークトラフィックがなくなりました。 –

関連する問題