web-dev-qa-db-ja.com

SQLサーバーテーブルの挿入パフォーマンスの最適化

設定

データウェアハウスでは、ファクトテーブルを20ディメンションに結合しています。ファクトテーブルには、3,200万行と30列があります。これは一時的なステージングテーブルなので、テーブルの読み取りや書き込みを行う他のユーザーに対処する必要はありません。ベーステーブルから10列、それぞれのディメンションから20列を選択します。ディメンションテーブルは小さい(3〜15.000行)。結合されるフィールドは、整数とnvarcharの両方です。 SELECT ... INTOステートメントを使用しています。テーブルにインデックスはありません。

このクエリの実行速度は遅すぎるため、役に立ちません。

試してみたソリューション

クエリの処理に時間がかかりすぎるため、次の解決策を試しました。

  1. 20の結合を5つのテーブルの4つの結合に分割します。ただし、クエリのパフォーマンスは低いままです。
  2. 外部キー列にインデックスを配置します。時間の大幅な短縮はありません。
  3. 結合条件のフィールドが整数であることを確認してください。パフォーマンスが25%向上しました。私が探しているものではありません。
  4. Select intoではなく、insert intoステートメントを使用します。データベースは単純復旧モードですが、ログファイルの増大によりパフォーマンスが低下します。

これらの調査結果から、コストの89%がtable insertにあることを示す実際の実行計画を含めることにしました。その他のコストは、ファクトテーブルの8%のテーブルスキャンと、内部結合のハッシュマッチングの2%です。

ご質問

  1. 遅いテーブル挿入の考えられる理由は何ですか?
  2. 実行計画なしでこのボトルネックを特定する方法は何ですか?
  3. テーブル挿入のコストを削減するためにどのようなアクションを実行できますか?
8
Drizzt

遅いテーブル挿入の考えられる理由は何ですか?実行計画なしでこのボトルネックを特定する方法は何ですか?

SQL Serverのパフォーマンスを分析する方法 、特に 個々のクエリ実行待機時間の分析 に関する部分をお読みください。

テーブル挿入のコストを削減するためにどのようなアクションを実行できますか?

それは、パフォーマンス分析の結果に大きく依存します。まず第一に、[〜#〜] select [〜#〜]部分が可能な限り高速であることを確認します。問題がシングルスレッドの完全にログに記録された挿入であると仮定すると、いくつかの解決策は次のとおりです。

12
Remus Rusanu

以下は私の経験であり、他の誰かを助けるかもしれません。

あるデータベースから別のデータベースにデータを転送しようとしていて、途中でいくつかの変換も行っていました。多くの挿入を実行していた変換をテストし、途中で修正してから、挿入を再度テストするために削除しました。ただし、いくつかの挿入と切り捨ての後、クエリの実行が遅くなり、1つの単純な挿入が以前は約3分間実行されていたのに、最大で9分間かかりました。

  1. まず、SELECTの最適化から始めました。サブクエリの代わりに、#tempTablesを使用しました。これは少しスピードアップしましたが、まだ満足できるものではありませんでした。
  2. 違いがあったのは、インデックスの再構築と宛先データベースの統計の更新でした。これにより、挿入が約2分になりました。

したがって、これらの2つの戦略を試して、これがどのように機能するかを確認してください。

1
Kleidi