0

SQL Server 2005 が ADO​​.NET 2.0 を使用してクライアントによって発行された要求をどのように処理するかについて、誰かが光を当てることができますか? 以下は、SQL トレースの短縮出力です。接続プールが機能していることがわかります (プールされている接続は 1 つだけだと思います)。私には明らかではないのは、以下の for ループの各ループの監査ログイン、SQL:BatchStarting、RPC:Starting、監査ログアウトなど、非常に多くの sp_reset_connection 呼び出しがある理由です。tempdb と master データベースの間で常に切り替えが行われていることがわかります。これにより、次の接続が ConectionString 引数に基づいてプールからフェッチされて作成されたときに、コンテキストが失われたと結論付けることができます。

15 ミリ秒ごとに、1 秒あたり 100 ~ 200 回のログイン/ログアウトを取得できることがわかります (プロファイラーによって同時に報告されています)。15 ミリ秒後、1 秒あたり 100 ~ 200 回のログイン/ログアウトが再び発生します。

これが本番環境での非常に複雑な挿入クエリにどのように影響するかを明確にする必要があります。私は Enterprise Library 2006 を使用しています。コードは VS 2005 でコンパイルされています。これは、親子行をグループ化する 10,000 行のフラット ファイルを解析し、アプリケーション サーバーで実行し、リモート SQL で 2 つのストアド プロシージャを実行するコンソール アプリケーションです。親レコードを挿入する Server 2005 は、Identity 値を取得し、それを使用して 2 番目のストアド プロシージャを 1 回、2 回、または複数回 (場合によっては数千回) 呼び出して、子レコードを挿入します。子テーブルには、5 ~ 10 のインデックスを持つ 1,000 万近くのレコードがあり、その一部は非クラスター化されています。挿入された詳細レコードをアーカイブ テーブルにコピーする非常に複雑な挿入トリガーがあります。全体として、1 秒あたり 7 回の挿入しかありません。つまり、5 万件のレコードに 2 ~ 4 時間かかる可能性があります。

したがって、私の質問は、会社が10万件のレコードをロードし、毎日の計画を立て、フラットファイル注文として来るクライアント要求を満たすためのSLAを持っているため、レコードの挿入を改善する方法があるかどうかです。すぐにインポートされます)。60,000 をインポートするのに 4 時間かかっていたものが、30 分に短縮されます。

DataAdapter の BatchSize を使用して複数のストアド プロシージャ コールを送信したり、SQL Bulk insert を使用して DataReader または DataTable から複数の挿入をバッチ処理したり、SSIS 高速ロードを使用したりしようと考えていました。しかし、インデックスの再作成と統計の人口を適切に分析する方法がわかりません。おそらく、これが完了するまでに時間がかかる可能性があります。さらに悪いことに、会社はレポートに最大のテーブルを使用し、他のオンライン処理とインデックスを削除できません。フィールドに値を設定してトランザクションを手動で管理し、その値を他のアプリケーションがコミットされた行を取得するために使用している新しい値に変更するトランザクション更新を行います。

この問題にアプローチする方法を教えてください。今のところ、別のデータベースに最小限のログを記録し、インデックスを持たないステージング テーブルを作成しようとしています。バッチ処理された (大規模な) 親子挿入を試みます。Production DB には単純な復旧モデルがあると思いますが、完全な復旧になる可能性があります。.NET コンソール アプリケーションで使用されている DB ユーザーが bulkadmin ロールを持っている場合、その一括挿入のログは最小限に抑えられます。テーブルがクラスター化されていて、挿入する多くの非クラスター化インデックスが行ごとにログに記録されることを理解しています。

接続プーリングは機能していますが、多くのログイン/ログアウトがあります。なんで?

for (int i = 1; i <= 10000; i++){ using (SqlConnection conn = new SqlConnection("server=(local);database=master;integrated security=sspi;")) {conn.Open(); using (SqlCommand cmd = conn.CreateCommand()){ cmd.CommandText = "tempdb を使用"; cmd.ExecuteNonQuery();}}}

SQL Server プロファイラー トレース:

監査ログイン マスター 2010-01-13 23:18:45.337 1 - 非プール
SQL:BatchStarting use tempdb master 2010-01-13 23:18:45.337
RPC:Starting exec sp_reset_conn tempdb 2010-01-13 23:18:45.337
監査ログアウトtempdb 2010-01-13 23:18:45.337 2 - プールされた
監査ログイン -- ネットワーク プロトコル マスター 2010-01-13 23:18:45.383 2 - プール
された SQL: BatchStarting は tempdb マスターを使用 2010-01-13 23:18:45.383
RPC: exec sp_reset_conn tempdb 2010-01-13 23:18:45.383 の開始

監査ログアウト tempdb 2010-01-13 23:18:45.383 2 - プール済み
監査ログイン -- ネットワーク プロトコル マスター 2010-01-13 23:18:45.383 2 - プール
された SQL:BatchStarting use tempdb master 2010-01-13 23:18:45.383
RPC:Starting exec sp_reset_conn tempdb 2010-01-13 23:18 :45.383
監査ログアウト tempdb 2010-01-13 23:18:45.383 2 - プール

4

2 に答える 2

1

「ログファイルに書き込む」とはどういう意味ですか。フラットファイルを解析し、ローカルフィールド変換を行い、親行と詳細行に基づいて計算を行い、ファイルシステム上の区切りファイルまたはBCP fmtファイルで期待される形式で出力し、一括挿入を使用する必要があるということですか。私はこれらのテクニックのいずれかを使用することを考えています:eggheadcafe.comのSqlBulkCopyでコピー操作をスピードアップ

プロデューサー/コンシューマーパターン http://sqlblog.com/blogs/alberto_ferrari/archive/2009/11/30/sqlbulkcopy-performance-analysis.aspx

ありがとう、ラッド

于 2010-01-14T17:46:10.710 に答える
0

挿入頻度の高い環境で、挿入を要求しているユーザーが実際の挿入の結果としてすぐにデータを必要としない場合は、挿入をバッチ処理することを強くお勧めします。200 人の異なるユーザーが同時に同じテーブルに挿入しようとする代わりに、(a) ログ ファイルに書き込み、次に BULK INSERT / BCP / SSIS を使用して希望の頻度でデータをインポートすることができます (バランスデータを実際にデータベースに反映する必要がある速度と、アクティビティをどの程度分散させたいか)、または (b) いくつかの異なるステージング テーブルに書き込み、希望する頻度でそれらを再度切り上げます。(a) と (b) の両方が競合を大幅に軽減します。(a) データベースを完全にオフラインにすることができ、アプリケーションは問題なく動作するため、わずかに優れています。

于 2010-01-14T14:14:49.193 に答える