ステートメントの実行速度がネットワーク接続に依存するのはなぜですか?


31

T-SQLの実行速度は、サーバーに対するネットワーク接続の待機時間に依存しているようです。SQL Serverがクライアントにレポートするものがない場合、実行されるまで実行されますが、テストでは別の話が示されます。

create procedure UselessLoop
  @I int
as
declare @D datetime = getdate()
while @I > 0 set @I -= 1
print datediff(millisecond, @D, getdate())

exec UselessLoop 100000

Server    Milliseconds
local     53
nearby    63
faraway   660

exec UselessLoop 1000000

Server    Milliseconds
local     546
nearby    640
faraway   6183

テストは、SSMSを使用して異なるコンピューターから同じサーバーに対して実行されます。ローカルはサーバーから実行され、近くは同じローカルネットワーク上にあり、遠くは1ギガビットファイバーで接続された500 km離れた別のオフィスから実行されます。

実行されるステートメントの数に直接依存する、SQL Serverとクライアントの間で行われている通信が明らかに存在します。

Wiresharkを使用して転送内容を確認しましたが、それほど理解しているとは言えませんが、22740パケットで合計26 MBを交換するtcp.streamでした。

代わりに役に立たない関数はどうですか?

create function dbo.UDFUselessLoop(@I int)
returns int
as
begin
  declare @D datetime = getdate()
  while @I > 0 set @I -= 1
  return datediff(millisecond, @D, getdate())
end

print dbo.UDFUselessLoop(1000000)

実行元に関係なく、406ミリ秒で実行されます。ループ内でクライアントとの通信がないように見えます。


3
私の質問にもこの回答を参照してくださいstackoverflow.com/a/1547539
gbn

回答:


33

実行されるステートメントの数に直接依存する、SQL Serverとクライアントの間で行われている通信が明らかに存在します。

はいあります。既定では、SQL Server はストアドプロシージャ内のすべてのステートメントの後にTDS DONE_IN_PROCメッセージを送信します。メッセージは、完了したステートメントのステータスと行カウント情報をクライアントに伝えます。

T-SQLコマンドを使用して、これらのメッセージの送信を抑制することができます。

SET NOCOUNT ON;

以下は、このコマンドのBooks Onlineエントリからの抜粋(私の強調)です。

実際のデータをあまり返さない複数のステートメントを含むストアドプロシージャ、またはTransact-SQLループを含むプロシージャの場合、ネットワークトラフィックが大幅に削減されるため、SET NOCOUNTをONに設定するとパフォーマンスが大幅に向上します。

関連するQ&A:単純なループの結果、ASYNC_NETWORK_IOが待機するのはなぜですか?

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.