6

これは一般的なシナリオですが、どの方法がパフォーマンスを最適化する方法であり、ベスト プラクティスであるかを知りたかったのです。

ID、名前、およびその他の 2 つのフィールドの 4 つの列を持つテーブルがあります。Id は PK で、name は一意のキーです。Excelファイルからデータを読み取り、ドメインオブジェクトの各行の値を入力して保存しています。保存時に同名のレコードが既に存在するかどうかを確認し、存在する場合は更新したい。それ以外の場合は、新しいレコードとして保存します。

名前の通常の選択クエリでそれを実行し、null をチェックし、その挿入または更新に基づいて実行できますが、Excel ファイルから読み取る行が数千あり、要求された非機能要件は performanceです。

それでは、このシナリオを処理するための最良の方法についてアドバイスをお願いします。私はまだ永続化レイヤー部分のコーディングを開始していないので、あなたの提案に従って ORM またはプレーンな jdbc に切り替えることができます。

編集: 名前を主キーとして使用する場合、ORM から saveOrUpdate またはマージを使用して、ニーズを満たすことができると思います。それは良い考えですか?ありがとう、よろしく、プラサート。

4

2 に答える 2

3

最速の方法は、データベースに接続して多数のステートメントを使用するのではなく、データベース自体ですべての挿入/更新を実行することだと思います。

これは Oracle 固有のものですが、他のデータベースにも同様の概念がある可能性があることに注意してください。

次のアプローチを使用します。まず、Excel データを CSV ファイルとしてデータベース サーバーに保存し ( /mydatadir/mydata.csv)、次に Oracle で外部テーブルを使用します。

create or replace directory data_dir as '/mydatadir/';
create table external_table (
  id number(18),
  name varchar2(30),
  otherfield1 varchar2(40),
  otherfield2 varchar2(40))
organization external (
  type oracle_loader
  default directory data_dir
  access parameters
  ( fields terminated by ',' )
  location ('mydata.csv')
)

(注: 外部テーブルは毎回設定する必要はありません)

次に、次のコマンドを使用して、データをテーブルにマージできます。

merge into yourtable t
using external_table e
on t.name = e.name
when matched then
   update set t.id = e.id, 
              t.otherfield1 = e.otherfield1, 
              t.otherfield2 = t.otherfield2
when not matched then
   insert (t.id, t.name, t.otherfield1, t.otherfield2)
   values (e.id, e.name, e.otherfield1, e.otherfield2)

これにより、1 つの Oracle コマンドで行がアップサートyourtableされるため、すべての作業はデータベースによって実行されます。

編集:

このmergeコマンドは、プレーンな JDBC を介して発行できます (ただし、Spring のSimpleJdbcTemplateを使用することを好みます) 。

EDIT2:

MySQL では、次の構成を使用してマージを実行できます。

insert into yourtable (id, name, otherfield1, otherfield2)
values (?, ?, ?, ?), 
       (?, ?, ?, ?), 
       (?, ?, ?, ?) --repeat for each row in the Excel sheet...
on duplicate Key update
set otherfield1 = values(otherfield1),
    otherfield2 = values(otherfield2)

これはプレーンな JDBC ステートメントとして発行でき、個別の更新と挿入よりも優れています。これらをスプレッドシートから (たとえば) 100 行のバッチで呼び出すことができます。これは、Excel シートの 100 行ごとに 1 回の JDBC 呼び出しを意味し、適切に実行されるはずです。これにより、外部テーブルなしでそれを行うことができます (これを機能させるには、name 列に UNIQUE インデックスが必要です。変更が必要な場合に外部キーで問題が発生する可能性があるため、主キーは変更しません)誰かの名前)。

MySQLには外部テーブルの概念もあります。これは、上記のようにデータをバッチとして挿入するよりも高速だと思います。csv ファイルが正しい場所にアップロードされている限り、インポートは迅速に行われます。

于 2012-04-11T08:08:46.747 に答える
0

セット内のすべての名前を読み取り、Excel ファイルから読み取った名前のセットとの使用の組み合わせを差し引くのが合理的かもしれません。

Set dbSet=//fill it from SQl query;
Set newSet//fill it from the file;

newSet.removeAll(dbSet); //left non existing ones to be inserted.

originalNewSet (イニシャルのクローンである可能性があります)

originalNewSet.removeAll(insertingSet); //left records to be updated.
于 2012-04-11T06:36:04.093 に答える