5

MS Access テーブルに 800000 レコードを挿入する必要があります。Delphi 2007 とそのTAdoXxxxコンポーネントを使用しています。テーブルには、いくつかの整数フィールド、1 つの浮動小数点フィールド、および 1 つの文字のみを含む 1 つのテキスト フィールドが含まれています。整数フィールド (autoinc ではない) の 1 つに主キーがあり、別の整数フィールドと float フィールドに 2 つのインデックスがあります。

を使用したデータの挿入にはAdoTable.AppendRecord(...)10 分以上かかります。これは、ユーザーがプログラムで新しいデータベースの使用を開始するたびに行われるため、許容できません。データが別のデータベース ( からはアクセスできないADO) から取得されているため、テーブルを事前入力できません。

tAdoCommandレコードをタブ区切りのテキスト ファイルに書き込み、オブジェクトを使用して実行することで、約 1 分に短縮できました。

insert into table (...) select * from [filename.txt] in "c:\somedir" "Text;HDR=Yes"

しかし、私はこれのオーバーヘッドが好きではありません。

もっと良い方法があるに違いない、と私は思う。

編集:

いくつかの追加情報:

  • MS Access を選択した理由は、ターゲット マシンに追加インストールする必要がなく、データベース全体が簡単にコピーできる 1 つのファイルに含まれているためです。
  • これはシングル ユーザー アプリケーションです。
  • データは一度だけ挿入され、データベースの存続期間中は変更されません。ただし、テーブルには、別のデータベースの対応するレコードがユーザーによって処理されたことを示すフラグとして使用される 1 つの追加フィールドが含まれています。
  • 1 分(最大 3 分も) で問題ありませんが、私のソリューション機能しますが、複雑すぎるように思われるので、もっと簡単な方法があるはずだと考えました。
  • データが挿入されると、テーブルのパフォーマンスは非常に良好です。
  • Access データベースを操作するプログラムの機能の計画/実装を開始したとき、テーブルは必要ありませんでした。それが必要になったのは、顧客から別の機能が要求されたときだけでした。(いつもそうじゃない?)

編集:

これまでに得たすべての回答から、Access テーブルに大量のデータを挿入するための最速の方法を既に理解しているようです。皆さんのおかげで、私はあなたの助けに感謝します.

4

16 に答える 16

9

800K レコードのデータはデータベースの存続期間中は変更されないとおっしゃっていたので、テキスト ファイルにテーブルとしてリンクし、挿入を完全にスキップすることをお勧めします。

どうしてもデータベースに取り込むと、1 分間で 800,000 レコードは 13,000/秒を超えます。MS Access でそれを打ち負かすつもりはないと思います。

ユーザーへの応答性を高めたい場合は、最小限のデータ セットをロードし、作業中に残りをロードするバックグラウンド スレッドを設定することを検討してください。

于 2009-02-06T20:31:51.837 に答える
5

インデックスがなければもっと速いでしょう。インポート後に追加できますか?

このスレッドには、興味深いと思われる提案がいくつかありますMSAccess ディスクの書き込みが遅い

于 2009-02-06T20:29:13.730 に答える
4

テキスト ファイルをスキップし、ODBC または OLEDB を使用してソース テーブルから直接インポートするのはどうでしょうか。これは、FROM 句を変更して、ソース テーブル名と適切な接続文字列を FROM 句の IN '' 部分として使用することを意味します。

編集: 実際には、元の形式は xBase であるとおっしゃっています。そのため、ODBC や OLEDB を必要とする代わりに、Jet の一部である xBase ISAM を使用できるはずです。それは次のようになります。

INSERT INTO table (...) 
SELECT * 
FROM tablename IN 'c:\somedir\'[dBase 5.0;HDR=NO;IMEX=2;];

それを微調整する必要があるかもしれません-DBFファイルを指すリンクテーブルの接続文字列を取得したので、パラメーターがわずかに異なる場合があります。

于 2009-02-06T22:21:59.883 に答える
3

別アレンジはいかがでしょうか…

必要なこのテーブルを含む既存の Access データベース ファイルのコピーを作成し、この 1 つの大きなテーブル以外の他のすべてのデータを削除するオプションはありますか (Access に " SQLサーバーでテーブルを切り捨てます)?

于 2009-02-06T20:57:35.497 に答える
3

テキストベースのソリューションが最速のようですが、事前に割り当てられた MS Access を最後のサイズに近いサイズで取得できれば、より迅速に取得できます。これを行うには、典型的なユーザー データベースをいっぱいにし、アプリケーションを閉じて (バッファーがフラッシュされるように)、その大きなテーブルのすべてのレコードを手動で削除しますが、縮小/圧縮はしません。

したがって、そのファイルを使用して実際の充填を開始します。Access は追加のディスク領域を要求しません (またはほとんど要求しません)。MS Access にこれを自動化する方法があるかどうかは覚えていませんが、大いに役立つ可能性があります...

于 2010-09-14T18:46:24.387 に答える
3

MS Access を別のデータベースに置き換えます。あなたの状況では、 Sqliteが最良の選択であり、クライアント マシンにインストールする必要がなく、非常に高速なデータベースであり、最高の組み込みデータベース ソリューションの 1 つです。

Delphi では、次の 2 つの方法で使用できます。

  1. Sqlite Web サイトからデータベース エンジン Dll をダウンロードし、無料の Delphi コンポーネントを使用して、 Delphi SQLite コンポーネントSQLite4Delphiのようにアクセスできます。

  2. エンジンが組み込まれているDISQLite3を使用してください。アプリケーションでdllを配布する必要はありません。無料バージョンがあります;-)

それでも MS Access を使用する必要がある場合は、TADOTable を使用する代わりに、SQL Insert ステートメントで TAdoCommand を直接使用してみてください。TADOTable.Append を使用するよりも高速です。

于 2009-02-07T10:41:18.113 に答える
2

誰かが言ったように、1 分以内に 800,000 レコードをインポートすることはありません。それはもう本当に速いです。

ただし、挿入を行うための適切な方法 (DAO レコードセット) を使用する場合は、煩わしいテキスト ファイルへの変換ステップをスキップできます。StackOverflow で私が尋ねて回答した以前の質問を参照してください

DAO でも INSERT INTO を使用しないでください。遅いです。ADO も使用しないでください。遅いです。しかし、DAO + Delphi + Recordsets + DbEngine COM オブジェクトを (Access.Application オブジェクトを介してではなく) 直接インスタンス化すると、速度が大幅に向上します。

于 2010-09-14T19:45:27.497 に答える
1

あなたはある意味で正しい方向を見ています。1 つのステートメントを使用して一括挿入する方が、データを繰り返し処理して行ごとに挿入するよりも高速です。ファイルベースのデータベースであるアクセスは、反復的な書き込みで非常に遅くなります。

問題は、Access が内部で書き込みを最適化する方法を処理しており、実際にはそれを制御する方法がないことです。INSERT ステートメントの最大効率に達した可能性があります。速度を上げるには、アプリケーションを起動するたびにデータベースに 800,000 レコードを書き込む方法がないかどうかを評価する必要があります。

于 2009-02-06T20:30:37.223 に答える
1

SQL Server Express (無料) を入手し、Access an external table から接続します。SQL Express は、MS Access よりもはるかに高速です。

于 2009-02-06T20:31:37.640 に答える
1

既存の(ただし空の)データベースを埋めるのではなく、データベースを事前に埋めて、ファイル自体を渡します。

入力する必要があるデータが変更された場合は、少しのコードを使用してサーバー上で ODBC アクセス データベース (MDB ファイル) の同期を維持し、メイン データベースの変更を確認してアクセス データベースにコピーします。

ユーザーが新しいデータベースを要求したら、MDB を圧縮して転送し、開きます。

または、データを開いてデータベースに直接挿入するコードを見つけることができる場合もあります。

代わりに、より高速にアクセスしてインポートできる別の形式 (csv 以外) を見つけることができる場合があります。

-アダム

于 2009-02-06T21:03:56.280 に答える
0

ディスクの回転速度はどれくらいですか?7200RPMの場合、3分間で800,000行は、ディスク1回転あたり37行のままです。私はあなたがそれよりもはるかにうまくいくとは思わない。

一方、プロセスを合理化することが目標である場合、テーブルリンクはどうですか?

ADOを介してソースデータベースにアクセスできないと言います。ソースデータベースのテーブルまたはビューへのMSAccessでテーブルリンクを設定できますか?次に、テーブルリンクからの単純な追加クエリにより、データがソースデータベースからターゲットデータベースにコピーされます。よくわかりませんが、かなり速いと思います。

実行時までテーブルリンクを設定できない場合は、ADOを介してプログラムでテーブルリンクを作成し、プログラムで追加クエリを作成してから、追加クエリを呼び出すことができます。

于 2009-02-09T07:36:49.163 に答える
0

800,000 レコードは作成ごとにどのくらい変化しますか? 新しいデータベースを作成するときに、レコードを事前に入力してから、外部データベースで変更されたレコードのみを更新することは可能でしょうか?

これにより、新しいデータベース ファイルをより迅速に作成できる場合があります。

于 2009-02-07T09:07:07.570 に答える
0

adLockBatchOptimisticおそらく、ロック モードと CursorLocationを使用して ADO レコードセットをテーブルに開きadUseClient、すべてのデータをレコードセットに書き込んでから、バッチ更新 ( rs.UpdateBatch) を実行できます。

于 2009-02-06T20:34:30.460 に答える
0

また、ファイルのコピーにかかる時間を確認してください。これは、データを書き込む速度の下限になります。db のような SQL では、通常、その速度に近づくにはバルク ロード ユーティリティが必要です。私の知る限り、MS は、bcp のように MS Access テーブルに直接書き込むツールを作成したことはありません。特殊な ETL ツールは、SSIS がメモリ内で変換を行う方法など、挿入に関連するいくつかのステップも最適化します。DTS にもいくつかの最適化があります。

于 2009-02-06T21:02:07.313 に答える
-3

HI最良の方法は、txtファイルからの一括挿入です。レコードをtxtファイルに挿入してから、txtファイルをテーブルに一括挿入する必要があると言われているため、その時間は3秒未満である必要があります。

于 2010-09-14T10:34:55.910 に答える