web-dev-qa-db-ja.com

特定のテーブルへの挿入が遅い理由を教えてください。

SQLテーブルのINSERTは、いくつかの理由で遅くなる可能性があることを知っています。

  • テーブル上のINSERT TRIGGERの存在
  • チェックする必要がある多くの強制された制約(通常は外部キー)
  • テーブルの中央に行が挿入されると、クラスター化インデックスでページが分割される
  • 関連するすべての非クラスター化インデックスの更新
  • テーブルの他のアクティビティからのブロック
  • 悪いIO書き込み応答時間
  • ...私が逃した何か?

特定のケースでどちらが原因であるかをどのようにして確認できますかページ分割、非クラスター化インデックスの更新、その他すべての影響をどのように測定できますか?

(一時テーブルから)一度に約10,000行を挿入するストアドプロシージャがあり、1万行あたり約90秒かかります。他のspidがタイムアウトするため、これは許容できないほど低速です。

実行プランを確認したところ、FLUルックアップのINSERT CLUSTERED INDEXタスクとすべてのINDEX SEEKSが表示されましたが、それでも、なぜこれほど時間がかかるのかはわかりません。トリガーはありませんが、テーブルには少数のFKey(適切にインデックスが付けられているように見える)があります。

これはSQL 2000データベースです。

30
BradC

あなたが見ることができるいくつかのもの...

バッチサイズを10000から2000や1000などの小さい値に減らします(行サイズの大きさは言われていません)。

IO Statsをオンにして、FKルックアップがどの程度IOを取っているかを確認します。

挿入が発生したときに引き起こされる待機は何ですか(master.dbo.sysprocesses)?

ここから始めましょう。

10
mrdenny

ブラッド、

クエリの待機統計を調べる必要があります。 SQL 2000では、DBCC SQLPERF( "待機統計")構文を使用してこれらの詳細を取得できます。

7
SQLRockstar

クエリのパフォーマンスを分析するときに探していることを言うことができます。多分それは役立ちます。

  • クエリ実行プランを分析し、インデックススキャン、テーブルスキャン、SQLデータ型のconvert_implicit関数の使用、並列性をチェックします。
  • sET STATISTICS IO ONおよびSET STATISTICS TIME ONでクエリを実行して、各挿入の実行時間と読み取り/書き込みioを確認します。
  • セッションspidのsysprocessesからの待ち時間を確認してください。
  • プロファイラーを実行し、標準テンプレートを選択します。以下を選択します:パフォーマンス統計(繰り返しの場合、プランは何度もコンパイルされます-良くありません)、RPC:completed、SQL:batchcompletedおよびSQL:batchstarting。それらに列rowcountsを追加して、バッチ内の行数を正確に確認します。結果をフィルタリングして、クエリのみを表示します。
  • 最後に収集Page Life Expectancyカウンタからウィンドウのperfmonまで。300未満(5分)の場合、SQLのメモリが不足しています。また、ディスクカウンターを収集します。ディスクキューの長さディスク時間(データファイルドライブ)、ディスク時間(ログファイルドライブ)ディスクに圧力がないかどうかを確認します。
6
yrushka

使用してみてください:

SET STATISTICS IO ON

そして

SET STATISTICS PROFILE ON

統計IO

最も多くのテーブルスキャン、論理読み取り、および物理読み取りを実行しているテーブルを特定するのに役立ちます(これらの3つを使用して、クエリプランのどの部分が最も調整が必要かを調べます)

統計プロファイル

主にクエリプランを表形式で返します。次に、IOとCPU列を見て、クエリで最もコストがかかっているものを探します(一時テーブルのテーブルスキャンですか)。クラスター化されたキーに挿入するために行うソートとの比較など...)

5