0

以下に示すようにループ挿入を行っています(方法A)。ループごとにデータベースを呼び出すのは良い考えではないようです。別の方法として、SProcでコンマ区切りの文字列をループして挿入を実行し、DBへのエントリを1つだけにすることもできます。パフォーマンスの面で大幅な改善はありますか?:

方法A:

foreach (DataRow row in dt.Rows) 
{
    userBll = new UserBLL();
    UserId = (Guid)row["UserId"];
    // Call userBll method to insert into SQL Server with UserId as one of the parameter.
}

方法B:

string UserIds = "Tom, Jerry, 007"; // Assuming we already concatenate the strings. So no loops this time here.
userBll = new UserBLL();  
// Call userBll method to insert into SQL Server with 'UserIds' as parameter.

方法BSProc/SProcでループ挿入を実行します。

if right(rtrim(@UserIds ), 1) <> ','
    SELECT @string = @UserIds + ','

SELECT @pos =  patindex('%,%' , @UserIds )

while @pos <> 0 
begin
    SELECT @piece = left(@v, (@pos-1))

    -- Perform the insert here

    SELECT @UserIds = stuff(@string, 1, @pos, '')
    SELECT @pos =  patindex('%,%' , @UserIds )
end
4

4 に答える 4

1

通常、クエリが少ないほど、処理が速くなります。そうは言っても、私の同僚は、.NET Framework の TSQL のラッパーである程度の成功を収めました。BULK INSERTこれは、Framework によって として提供されSqlBulkCopyます。 この MSDN ブログ エントリには、その使用方法が示されています。

主な「API」サンプルは次のとおりです (リンクされた記事からそのまま取得し、DataTable の内容を SQL に書き込みます)。

private void WriteToDatabase()
{
    // get your connection string
    string connString = "";
    // connect to SQL
    using (SqlConnection connection = 
            new SqlConnection(connString))
    {
        // make sure to enable triggers
        // more on triggers in next post
        SqlBulkCopy bulkCopy = 
            new SqlBulkCopy
            (
            connection, 
            SqlBulkCopyOptions.TableLock | 
            SqlBulkCopyOptions.FireTriggers | 
            SqlBulkCopyOptions.UseInternalTransaction,
            null
            );

        // set the destination table name
        bulkCopy.DestinationTableName = this.tableName;
        connection.Open();

        // write the data in the "dataTable"
        bulkCopy.WriteToServer(dataTable);
        connection.Close();
    }
    // reset
    this.dataTable.Clear();
    this.recordCount = 0;
}

リンクされた記事では、このメカニズムを活用するために何をする必要があるかを説明しています。

于 2013-02-26T15:03:33.043 に答える
1

私の経験では、レコードごとに行う必要のないことが 3 つあります。

  1. 行ごとに SQL 接続を開閉します。この問題は、ADO.NET 接続プールによって処理されます。プーリングを無効にしていない限り、心配する必要はありません。

  2. 行ごとのデータベース往復。これは、ネットワーク帯域幅やネットワーク遅延に関するものではなく、クライアント側のスレッドのスリープに関するものである傾向があります。ウェイクアップするたびにクライアント側でかなりの量の作業が必要な場合、またはタイム スライスを無駄にしている場合。

  3. 行ごとに SQL トランザクション ログを開いたり閉じたりします。ログを開いたり閉じたりするのは自由ではありませんが、あまりにも長く開いたままにしたくないでしょう。1 つのトランザクションで多くの挿入を行いますが、多すぎないようにします。

これらのいずれにおいても、リクエストごとに 1 行から 10 行へと多くの改善が見られるでしょう。これは、バッチを送信する前にクライアント側で 10 個の挿入ステートメントを作成することで実現できます。

リストを proc に送信するアプローチについては、Sommarskogによって非常に詳細に書かれています。

于 2013-02-26T15:11:43.563 に答える
0

これには、一括挿入機能を使用できます。

詳細については、このブログを参照してください: http://blogs.msdn.com/b/nikhilsi/archive/2008/06/11/bulk-insert-into-sql-from-c-app.aspx

于 2013-02-26T15:05:28.287 に答える
0

特定の型の複数の入力値を使用して挿入のパフォーマンスを向上させたい場合は、テーブル値パラメーターを確認することをお勧めします。

また、サンプルはこちらで見つけることができ、それらを使用するサンプル コードが示されています。

于 2013-02-26T14:58:11.183 に答える