web-dev-qa-db-ja.com

SQL Serverがクエリの実行中に一部の行を返すのはなぜですか?

「実行」を押すと、いくつかの行が表示されて成長し続けるクエリがありますが、クエリはまだ終わっていません。ただし、クエリが終了するまで待機することもあります。

なぜこれが起こるのですか?これを制御する方法はありますか?

33
Racer SQL

その答えは、いつものように(大抵の場合)、実行計画にあります。

これらの行の処理を開始してダウンストリームに渡す前に、すべての行に到達する必要がある特定の演算子があります。次に例を示します。

  • ハッシュ結合(ハッシュテーブルの作成時)
  • ハッシュマッチ
  • 並べ替え(ハッシュフローの区別なし)

これらは、ブロッキングまたはストップアンドゴーオペレーターのいずれかと呼ばれ、オプティマイザーがデータを見つけるために大量のデータを処理する必要があると判断した場合に選択されます。

ストリーミングを開始したり、見つかった行をすぐに渡したりできる演算子は他にもあります

  • ネストされたループ
  • インデックスでサポートされているマージ結合
  • ストリーム集合体

クエリがすぐにデータを返し始めたがすぐには終了しない場合、通常、オプティマイザが起動コストの低い演算子を使用していくつかの行をすばやく見つけて返す計画を選択したことを示しています。

これは、ユーザーまたはオプティマイザによって導入された行の目標が原因で発生する可能性があります。

また、何らかの理由(SARGabilityの欠如、パラメーターのスニッフィング、不十分な統計など)で誤った計画が選択された場合にも発生する可能性がありますが、それを理解するにはさらに掘り下げる必要があります。

詳細については、Rob Farleyのブログをチェックしてください here

そして、行の目標に関するポールホワイトのシリーズ hereherehere 、および here

また、SSMSについて話している場合、行が表示されるのは意志だけではなく、バッファ全体がいっぱいになると表示されることです。

43
Erik Darling

私があなたが観察しているものを理解している場合、これはManagement Studioが行をレンダリングする方法であり、SQL Serverが返す方法とはほとんど関係ありません行。実際、多くの場合、SSMSに大きな結果を返し、それらをグリッドにレンダリングしようとすると、SSMSが追い付かず、SQL Serverはアプリがさらに行を処理するのを待機することになります。この場合、SQL Serverが_ASYNC_NETWORK_IO_待機を累積しているのがわかります。

SSMSはグリッドを描画するよりも速くテキストを描画できるため、結果をグリッドではなく結果をテキストを使用して制御することもできますが、列の数と関連するデータ型によっては読みやすさに影響を与える可能性があります。どちらも、SSMSが実際に結果をそのペインに書き出すことを決定したときに影響を受けます。これは、出力バッファーがどの程度いっぱいであるかに依存します。

multipleステートメントがあり、出力結果をメッセージペインにレンダリングするようにバッファーを強制したい場合は、ステートメント間で小さな印刷トリックを使用できます。

_RAISERROR('', 0, 1) WITH NOWAIT;
_

しかし、これは、すべての出力が単一のステートメントからのものである場合に、SSMSで行をより速くレンダリングしようとする場合には役に立ちません。

より直接的には、SSMSでレンダリングする結果の数を制限することで制御できます。 100万行をグリッドに返すのにかかる時間について不満を言う人がよくいます。 SSMSグリッドの100万行でいったい誰が何をしようとしているのか、私にはわかりません。

OPTION (FAST 100) のようないくつかのハックがあり、最初の100行(または外側の_ORDER BY_)がない場合は100行ですが、残りの行の検索がはるかに遅くなり、全体としては非効率的な計画になるため、実際には頼りになるオプションではありません私見では。

14
Aaron Bertrand

あなたの質問はSQLServer自体についてではありませんが:

  • SQLサーバー
  • 通信網
  • クライアントアプリケーションとしてのSSMS

これを制御する方法はありますか?

短い答え

  1. sqlcmdまたはssms- mode of sqlcmdの代わりにssmsを試してください
  2. 接続とセッションの設定を確認する

長い答え

もちろん!しかしone-ない

  1. sqlcmdを使用して、またはssmsのsqlcmd- modeでクエリを実行します。
  2. ネットワークの役割を除外する場合は、共有メモリ接続を使用してサーバーでクエリを実行します。
  3. 共有メモリ接続を使用してもクエリのパフォーマンスが満足できない場合は、実行プランを分析してください。ネットワーク経由でクエリのパフォーマンスが悪い場合-ネットワークネットワーク管理者に問い合わせてください。クエリがSSMSでのみうまく機能しない場合-さらに読む。
  4. これで、問題がクライアント側(この場合はssms)にあることがわかります。 SSMSで接続とセッションの設定を確認します。 ssmsインターフェースを信じないとSQLプロファイラーで確認:spidで接続を見つけると、セッション設定の完全なリストが表示されます。 sqlcmdセッションの設定と比較してください。何もクリックしない場合-プロファイラーからクエリスクリプトにすべてのセッション設定をコピーし、sqlcmd- modeで実行し、設定を徐々に切り替えて原因を見つけます。

幸運を!

1
Alex Yu