16

最初のアクションの 1 つとして、クエリを使用して 750K レコードを一時テーブルに入れる sproc があります。一時テーブルに入力する前にインデックスを作成すると、テーブルに入力した後にインデックスを作成する場合と比較して、項目の実行に約 2 倍の時間がかかります。(インデックスは 1 つの列の整数であり、インデックスが作成されるテーブルはそれぞれ 1 つの整数の 2 つの列だけです。)

これは私には少しずれているように思えますが、ボンネットの下で何が起こっているのかをしっかりと理解しているわけではありません。誰もこれに対する答えを持っていますか?

4

9 に答える 9

42

クラスター化インデックスを作成すると、データがディスク上で物理的に順序付けられる方法に影響します。事後的にインデックスを追加し、データベース エンジンがデータの分散方法を認識したときに行を並べ替える方がよいでしょう。

たとえば、番号の付いたレンガでレンガの壁を構築し、番号が最も大きいレンガが壁の下部にくるようにする必要があるとします。ランダムな順序でレンガを 1 つずつ手渡された場合は、難しい作業になります。どのレンガが最大の番号になるか分からず、壁を取り壊さなければなりません。そして何度も作り直します。すべてのレンガが目の前に並んでいて、作業を整理できれば、そのタスクを処理するのがずっと簡単になります。

これがデータベース エンジンの場合です。ジョブ全体を知らせると、一度に 1 行ずつフィードするよりもはるかに効率的になります。

于 2008-08-26T19:19:27.710 に答える
6

これは、新しい行を挿入するたびに、データベース サーバーが計算を行う必要があるためです。基本的に、毎回テーブルのインデックスを再作成することになります。それほど高価な操作ではないように見えますが、そうではありませんが、多くの操作を一緒に行うと、効果が見え始めます。そのため、通常、行にデータを入力した後にインデックスを作成する必要があります。これは、1 回限りのコストになるためです。

于 2008-08-26T19:20:57.800 に答える
3

このように考えてください。


unorderedList = {5, 1,3}の場合、 orderedList
= {1,3,5}

両方のリストに 2 を追加します。
unorderedList = {5、1,3,2}、
orderedList = {1,2,3,5}

どのリストに追加しやすいと思いますか?

ところで、ロードの前に入力を注文すると、ブーストが得られます。

于 2008-08-26T19:22:08.873 に答える
3

後で大量にロードする場合は、空のテーブルにインデックスを作成しないでください。テーブルのデータが変更されるたびにインデックスを維持する必要があるため、テーブルに挿入するたびにインデックスが再計算されていると想像してください (これはコストのかかる操作です)。最初にテーブルをロードし、ロードが終了したらインデックスを作成します。それがパフォーマンスの違いです。

于 2008-08-26T19:17:34.173 に答える
2

大規模なデータ操作操作を実行した後、基になるインデックスを頻繁に更新する必要があります。これは、UPDATE STATISTICS [テーブル] ステートメントを使用して行うことができます。

もう 1 つのオプションは、インデックスを削除して再作成することです。これにより、大量のデータを挿入する場合に、挿入がはるかに高速に実行される可能性があります。それをストアド プロシージャに組み込むこともできます。

于 2008-08-26T19:19:15.463 に答える
1

インデックスのオーバーヘッドに加えて、同じ理由で各クエリをトランザクションとして実行することはお勧めできません。1つの明示的なトランザクション内で挿入のチャンク(たとえば100)を実行すると、パフォーマンスも向上するはずです。

于 2008-08-26T23:38:03.283 に答える
1

これは、SQL Server がデータを含むテーブルにインデックスを付けると、インデックス付きの列の値の正確な統計を生成できるためです。SQL Server は統計を再計算する場合がありますが、大量の挿入を実行すると、前回の統計の計算後に値の分布が変わる場合があります。

統計が古いという事実は、Query Analyzer で検出できます。特定のテーブル スキャンで、予想される行数が実際に処理された行数と大きく異なることがわかります。

すべてのデータを挿入した後、UPDATE STATISTICSを使用して値の分布を再計算する必要があります。その後、パフォーマンスの違いは見られません。

于 2008-08-26T19:21:50.373 に答える
1

テーブルにインデックスがある場合、テーブルにデータを追加すると、SQL Server はテーブルを並べ替えて、新しいレコード用の適切な場所を確保する必要があります。大量のデータを追加する場合は、何度も並べ替える必要があります。データがロードされた後にのみインデックスを作成することで、並べ替えは 1 回だけで済みます。

もちろん、レコードをインデックス順にインポートする場合は、それほど重要ではありません。

于 2008-08-26T19:22:14.553 に答える
1

これは、挿入するデータがインデックスの順序になっていない場合、SQL はページを分割して追加行用のスペースを確保し、それらを論理的にまとめる必要があるためです。

于 2008-08-26T19:16:28.747 に答える