2

OLEDBConnection を使用して、約 100 万件のレコードを MS Access DB に挿入する C++ プログラムがあります。そのINSERT INTOために、レコードを挿入するためにクエリを何百万回も実行しましたが、これにはかなりの時間がかかりました。

データはプログラムで配列の形式で生成されますが、パフォーマンスを向上させるために 1 つのステップでデータをデータベースにロードできる他の方法はありますか?

ありがとう!

現在レコードを挿入するために使用するループ

for (int i = 0; i < populationSize; i++){
    insertSQL = "INSERT INTO [" + pTableName + "] (" + columnsName + ") VALUES (" + columnsValue[i] + ");";`
    outputDBConn->runSQLEdit(insertSQL);
}

SQL クエリを実行するメソッド

void DBConnector::runSQLEdit(String^ query){
    SQLCMD = gcnew OleDbCommand( query, dbConnection );
    SQLCMD->CommandTimeout = 30;
    dbConnection->Open();
    SQLCMD->ExecuteNonQuery();
    dbConnection->Close();
    }
4

2 に答える 2

3

各挿入ステートメントの接続を開いたり閉じたりするのは非常に非効率的です。

標準的なアプローチは次のようになります。

  1. 接続を開きます。
  2. サポートされている場合、トランザクションを開始します。(これは、多くの場合、トランザクションを持つデータベースにとって非常に重要です。)
  3. 入れる。必要に応じてこの手順を繰り返します。
  4. サポートされている場合、トランザクションをコミットします。
  5. 接続を閉じます。

更新:以下は MS Access には適用されません。Accessは、リテラルからの複数行の挿入をサポートしていません 。既存のデータ ソースからの複数行の挿入のみがサポートされています。(ただし、これは機能する可能性のある「回避策」です。いずれにせよ、最も重要なことは、おそらくトランザクション数を制限することです。)

もう 1 つできることは、一度に複数のレコードを追加する単一の挿入コマンドを作成することです。これは、複数のステートメントまたは複数レコードの挿入 (サポートされている場合) のいずれかで実行できます。上記よりも大幅に高速である場合とそうでない場合があり(ネットワーク遅延やデータベース エンジンなどの他の要因によって異なります)、データベースの制限内に収まるように適合させる必要がある可能性があります (たとえば、数百のレコードに対してのみ実行可能である可能性があります)。一気に)。これは、上記のように接続/トランザクションを適切に使用した後にのみ考慮する必要があります。

「一括挿入」ライブラリ/モジュールがすでに作成されていても驚かないでしょう...そして私はMS Accessを使用していないので、上記の提案が役立つことを願っています:-)

ハッピーコーディング。

于 2011-12-22T06:59:31.600 に答える
1

コマンドごとに 1 つの挿入を行わないでください。コードを次のように変更します。

string strSQLCommand;
for (int i = 0; i < populationSize; i++){
strSQLCommand += "INSERT INTO [" + pTableName + "] (" + columnsName + ") VALUES (" + columnsValue[i] + ");";`
}
outputDBConn->runSQLEdit(strSQLCommand );

コマンドの最大バッファサイズがわからないので、いくつかのチェックを行ってから、X挿入ごとにいくつかの「ブレーク」を行うための最良の値を取得してください。

于 2011-12-22T12:10:07.143 に答える