sql >> データベース >  >> RDS >> Database

パフォーマンスの驚きと仮定:カウントをオンに設定

    Management Studioを使用したことがある場合、この出力メッセージはおそらく見覚えがあるでしょう。

    (影響を受ける1行)

    これは、SQLServerのDONE_IN_PROCからのものです。 メッセージ。結果を返したSQLステートメントが正常に完了したときに送信されます(実行プランの取得を含むため、実際に1つのクエリのみを実行したときにこれらのメッセージが2つ表示されます)。

    次のコマンドを使用して、これらのメッセージを抑制できます。

    SET NOCOUNT ON;

    どうしてそうするか?これらのメッセージはおしゃべりだからです 多くの場合、役に立たない 。悪い習慣とベストプラクティスのプレゼンテーションでは、SET NOCOUNT ON;の追加についてよく話します。 すべてのストアドプロシージャに適用し、アドホッククエリを送信するアプリケーションコードでオンにします。 (ただし、デバッグ中は、出力がそのような場合に役立つ可能性があるため、メッセージをオンに戻すためのフラグが必要になる場合があります。)

    私はいつも、このオプションをどこでもオンにするアドバイスは普遍的ではないという免責事項を追加しました。場合によります。古い学校のADOレコードセットは、実際にはこれらを結果セットとして解釈したため、事後にクエリに追加すると、すでに手動でスキップしているアプリケーションが実際に破損する可能性があります。そして、いくつかのORM(咳NHibernate咳 )実際に結果を解析して、DMLコマンドの成功を判断します(うーん!)。変更をテストしてください。

    ある時点で、これらのおしゃべりなメッセージが、特に低速のネットワークでパフォーマンスに影響を与える可能性があることを自分自身に証明したことを知っています。しかし、それは長い間であり、先週、ErinStellatoは私がそれを正式に文書化したことがあるかどうか私に尋ねました。私はしていませんので、ここに行きます。非常に単純なループを使用して、テーブル変数を100万回更新します。

    SET NOCOUNT OFF;
     
    DECLARE @i INT = 1;
    DECLARE @x TABLE(a INT);
    INSERT @x(a) VALUES(1);
     
    SELECT SYSDATETIME();
     
    WHILE @i < 1000000
    BEGIN
      UPDATE @x SET a = 1;
      SET @i += 1;
    END
     
    SELECT SYSDATETIME();

    あなたが気付くかもしれないいくつかのこと:

    • メッセージペインには、(1 row(s) affected)のインスタンスが殺到します。 メッセージ:

    • 最初のSELECT SYSDATETIME(); バッチ全体が完了するまで、結果ペインに表示されません。これは洪水によるものです。
    • このバッチの実行には約21秒かかりました。

    それでは、DONE_IN_PROCなしでこれを繰り返しましょう。 SET NOCOUNT OFF;を変更してメッセージを送信します SET NOCOUNT ON; もう一度実行してください。

    メッセージペインに影響を受ける行が表示されることはなくなりましたが、バッチの実行には21秒ほどかかりました。

    それから私は、ちょっと待って、何が起こっているのか知っていると思いました。私はローカルマシンを使用しており、ネットワークは関与せず、共有メモリを使用しています。SSDとRAMのゴブとゴブしかありません…

    そこで、リモートのAzure SQLデータベース(標準、S0、V12)に対してSSMSのローカルコピーを使用してテストを繰り返しました。今回は、反復を1,000,000から100,000に減らした後でも、クエリにかなり時間がかかりました。ただし、DONE_IN_PROCであるかどうかにかかわらず、パフォーマンスに明確な違いはありませんでした。 メッセージが送信されているかどうか。両方のバッチに約104秒かかり、これは多くの反復にわたって繰り返し可能でした。

    結論

    何年もの間、私はSET NOCOUNT ON;という印象で運営してきました。 パフォーマンス戦略の重要な部分でした。これは、おそらく別の時代に私が行った観察に基づいており、それは今日現れる可能性が低いです。

    そうは言っても、私は引き続きSET NOCOUNT ONを使用します 、今日のハードウェアでは、パフォーマンスに目立った違いはありません。可能な限りネットワークトラフィックを最小限に抑えることについては、今でもかなり強く感じています。帯域幅がはるかに制限されているテスト(誰かが私に貸してくれるAOL CDを持っているかもしれません)、またはメモリの量がManagementStudioの出力バッファ制限よりも少ないマシンを使用してテストを実装することを検討する必要があります。最悪のシナリオでは潜在的な影響はありません。それまでの間、アプリケーションのパフォーマンスは変わらないかもしれませんが、特にAzureのように、出力トラフィックに対して課金される可能性がある状況では、ウォレットがこの設定オプションを常にオンにするのに役立つ可能性があります。


    1. 画像をデータベースに直接保存しますか、それともbase64データとして保存しますか?

    2. カンマ区切りの値をOracleの行に変換するにはどうすればよいですか?

    3. execSQL:bindargsの方が優れていますか?

    4. MySQLエラー1264:列の値が範囲外です