10

このコードを使用して、データベースの空のテーブルに 100 万件のレコードを挿入しています。わかりましたので、多くのコードを使用せずに、既にデータを操作した時点から開始し、スキーマを次のように読み取りますDataTable

そう:

DataTable returnedDtViaLocalDbV11 = DtSqlLocalDb.GetDtViaConName(strConnName, queryStr, strReturnedDtName);

これで、ソース データベース テーブルのクローンとなるreturnedDtViaLocalDbV11新しいテーブルを作成できます。DataTable

DataTable NewDtForBlkInsert = returnedDtViaLocalDbV11.Clone();

Stopwatch SwSqlMdfLocalDb11 = Stopwatch.StartNew();
NewDtForBlkInsert.BeginLoadData();

for (int i = 0; i < 1000000; i++)
{
   NewDtForBlkInsert.LoadDataRow(new object[] { null, "NewShipperCompanyName"+i.ToString(), "NewShipperPhone" }, false);
}
NewDtForBlkInsert.EndLoadData();

DBRCL_SET.UpdateDBWithNewDtUsingSQLBulkCopy(NewDtForBlkInsert, tblClients._TblName, strConnName);

SwSqlMdfLocalDb11.Stop();

var ResSqlMdfLocalDbv11_0 = SwSqlMdfLocalDb11.ElapsedMilliseconds;

このコードは、5200ms で組み込み SQL データベース (localDb) に 100 万件のレコードを取り込みます。コードの残りの部分は、bulkCopy を実装しているだけですが、とにかく投稿します。

 public string UpdateDBWithNewDtUsingSQLBulkCopy(DataTable TheLocalDtToPush, string TheOnlineSQLTableName, string WebConfigConName)
 {
    //Open a connection to the database. 
    using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings[WebConfigConName].ConnectionString))
    {
       connection.Open();

       // Perform an initial count on the destination table.
       SqlCommand commandRowCount = new SqlCommand("SELECT COUNT(*) FROM "+TheOnlineSQLTableName +";", connection);
       long countStart = System.Convert.ToInt32(commandRowCount.ExecuteScalar());

       var nl = "\r\n";
       string retStrReport = "";
       retStrReport = string.Concat(string.Format("Starting row count = {0}", countStart), nl);
       retStrReport += string.Concat("==================================================", nl);
       // Create a table with some rows. 
       //DataTable newCustomers = TheLocalDtToPush;

       // Create the SqlBulkCopy object.  
       // Note that the column positions in the source DataTable  
       // match the column positions in the destination table so  
       // there is no need to map columns.  
       using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connection))
       {
          bulkCopy.DestinationTableName = TheOnlineSQLTableName;

          try
          {
             // Write from the source to the destination.
             for (int colIndex = 0; colIndex < TheLocalDtToPush.Columns.Count; colIndex++)
             {
                bulkCopy.ColumnMappings.Add(colIndex, colIndex);
             }
             bulkCopy.WriteToServer(TheLocalDtToPush);
          }

          catch (Exception ex)
          {
             Console.WriteLine(ex.Message);
          }
       }

       // Perform a final count on the destination  
       // table to see how many rows were added. 
       long countEnd = System.Convert.ToInt32(
       commandRowCount.ExecuteScalar());

       retStrReport += string.Concat("Ending row count = ", countEnd, nl);
       retStrReport += string.Concat("==================================================", nl);
       retStrReport += string.Concat((countEnd - countStart)," rows were added.", nl);
       retStrReport += string.Concat("New Customers Was updated successfully", nl, "END OF PROCESS !");
       //Console.ReadLine();
       return retStrReport;
   }
}

SQLサーバーへの接続を介して試してみると、約7000ミリ秒(せいぜい)で、平均で約7700ミリ秒でした。また、ランダムなkv nosqlデータベースを介して、約40秒かかりました(実際には、SQLバリアントのx2を通過したため、記録を保持していませんでした)。だから...私のコードでテストしていたものよりも速い方法はありますか?

編集

私はwin7 x64 8GB RAMを使用していますが、最も重要なことは(i5 3ghzとして)それほど優れていないと考えるべきです構成内の他の方法と比較するだけです

4

8 に答える 8

2

SSISを試しましたか?私は loacldb 接続を使用して SSIS パッケージを作成したことはありませんが、これは SSIS が適している種類のアクティビティです。

データ ソースが SQL Server の場合、リンク サーバーをセットアップするという別のアイデアがあります。これが localdb で機能するかどうかはわかりません。リンク サーバーを設定できる場合は、C# をすべてバイパスして、INSERT .. SELECT ... FROM ... SQL ステートメントでデータを読み込むことができます。

于 2013-06-25T12:32:27.070 に答える
1

使用できますDapper.NET。Dapper はマイクロ ORM であり、クエリを実行し、結果を厳密に型指定されたリストにマップします。コンピュータ ソフトウェアにおけるオブジェクト リレーショナル マッピング (ORM、O/RM、および O/R マッピング) は、オブジェクト指向プログラミング言語の互換性のない型システム間でデータを変換するためのプログラミング手法です。これにより、事実上、プログラミング言語内から使用できる「仮想オブジェクト データベース」が作成されます。

詳細については:

https://code.google.com/p/dapper-dot-net/をご覧ください

GitHub リポジトリ : https://github.com/SamSaffron/dapper-dot-net

于 2013-07-10T14:41:07.003 に答える
1

ループを削除... SQLでは、100万行のテーブルを作成してみてください...そして左結合でこれを挿入/選択データに使用します

于 2013-07-16T03:43:39.323 に答える
0

データベースに保存するすべての行に対して単一の XML ファイルを作成します。この XML を SQL ストアド プロシージャに渡し、すべてのレコードを 1 回の呼び出しだけで保存します。ただし、ストアド プロシージャは、すべてを読み取ってからテーブルに挿入できるように作成する必要があります。

于 2013-07-15T11:31:04.190 に答える
0

SSIS については Mike の意見に同意しますが、お使いの環境には適していません。ただし、クロス サーバー コールや一般的なデータ フロー プロセスを含む ETL プロセスでは、優れた組み込みツールであり、高度に統合されています。

100 万行の場合、一括挿入が必要になる可能性があります。行のサイズによっては、バッチでこれを行わない限り、ストアド プロシージャを実際に使用することはできません。データテーブルは、行のサイズにもよりますが、メモリがすぐにいっぱいになります。ストアド プロシージャを作成して、テーブル型を取得し、X 行ごとにそれを呼び出すこともできますが、より優れた、よりスケーラブルなソリューションが既にあるのに、なぜこれを行うのでしょうか。その 100 万行は、来年には 5,000 万行になる可能性があります。

私はSSISを少し使用しましたが、それが組織に適している場合は、それを見ることをお勧めしますが、それは1回限りの答えではなく、依存関係に値するものではありません.

于 2013-07-18T00:07:52.120 に答える
0

これが新しいプロジェクトである場合は、Entity Frameworkを使用することをお勧めします。この場合、必要なすべてのデータを含むオブジェクトで List<> を作成し、それを対応するテーブルに完全に追加するだけです。このようにして、必要なデータをすばやく取得し、すぐにデータベースに送信します。

于 2013-07-15T13:17:23.420 に答える
0

意味のないデータを作成するだけの場合は、ストアド プロシージャを作成し、それを .net 経由で呼び出すだけです。

実際のデータを渡す場合は、再度ストアド プロシージャに渡す方が高速ですが、テーブルを削除してデータを使用して再作成することをお勧めします。

一度に 1 行ずつ挿入すると、一度にすべてを挿入するよりも時間がかかります。書き込むインデックスがある場合は、さらに時間がかかります。

于 2013-06-28T19:20:30.367 に答える