2016-05-24 13 views
1

ファイルごとに10.000行以上のテキストファイルを読み込み、分割してJavaおよびUCanAccessを使用してAccessデータベースに挿入しようとしています。問題は、毎回(データベースが大きくなるにつれて)遅くなり、遅くなるということです。大きなテキストファイルからUCanAccessを使ってデータを挿入するのが非常に遅い

7つのテキストファイルを読み込んでデータベースに挿入すると、別のファイルを読み込むのに20分以上かかることがありました。

私はちょうど読書をしようとしたが、それは問題なく、データベースに実際に挿入されるので、正常に動作します。

N.B:JDBC-ODBCブリッジが使用できなくなったため、JavaでUCanAccessを初めて使用しました。別の解決方法の提案もあります。

答えて

0

現在の作業では、テキストファイルから大量のデータを直接データベースにインポートするだけで、洗練されたSQL操作は必要ありません.Jackcess APIを直接使用することを検討してください。

String csvFileSpec = "C:/Users/Gord/Desktop/BookData.csv"; 
String dbFileSpec = "C:/Users/Public/JackcessTest.accdb"; 
String tableName = "Book"; 

try (Database db = new DatabaseBuilder() 
     .setFile(new File(dbFileSpec)) 
     .setAutoSync(false) 
     .open()) { 

    new ImportUtil.Builder(db, tableName) 
      .setDelimiter(",") 
      .setUseExistingTable(true) 
      .setHeader(false) 
      .importFile(new File(csvFileSpec)); 

    // this is a try-with-resources block, 
    //  so db.close() happens automatically 
} 

または、手動入力のそれぞれの行を解析する必要がある場合は、行を挿入し、新しい行のためのオートナンバー型の値を取得する:たとえば、あなたがこのような何かを行うことができ、CSVファイルをインポートします、その後、コードをよりこのようになる:

String dbFileSpec = "C:/Users/Public/JackcessTest.accdb"; 
String tableName = "Book"; 
try (Database db = new DatabaseBuilder() 
     .setFile(new File(dbFileSpec)) 
     .setAutoSync(false) 
     .open()) { 

    // sample data (e.g., from parsing of an input line) 
    String title = "So, Anyway"; 
    String author = "Cleese, John"; 

    Table tbl = db.getTable(tableName); 
    Object[] rowData = tbl.addRow(Column.AUTO_NUMBER, title, author); 
    int newId = (int)rowData[0]; // retrieve generated AutoNumber 
    System.out.printf("row inserted with ID = %d%n", newId); 

    // this is a try-with-resources block, 
    //  so db.close() happens automatically 
} 

は、その主キーに基づいて、既存の行を更新するには、コードは以下のようになり

Table tbl = db.getTable(tableName); 
Row row = CursorBuilder.findRowByPrimaryKey(tbl, 3); // i.e., ID = 3 
if (row != null) { 
    // Note: column names are case-sensitive 
    row.put("Title", "The New Title For This Book"); 
    tbl.updateRow(row); 
} 

最大速度の場合は、データベースを開くときに.setAutoSync(false)を使用しましたが、AutoSyncを無効にすると、アップデートの実行中にアプリケーションが異常終了した場合、Accessデータベースファイルが破損している可能性があります。

+0

ありがとうございますが、ファイルを分割して、すべての行で部分文字列を使用して、SQLクエリーと文字列分割が必要です。 –

+0

@Yassine - SQLを使用して(PreparedStatementなど)一度に1つの行を挿入する場合、JackcessとそのAddRowメソッドを使用して同じ結果を達成することもできます。そうすれば、UCanAccess/HSQLDBオーバーヘッドを回避できます。 –

+0

はいPreparedStatementを使用して、各行を(最初の3文字に基づいて)subStringで分割し、変数に格納した後、JackcessとaddRowメソッドをどのように使用できますか? N.B:挿入後に使用するために、挿入された行の主キーを返すためにAUTO_GENERATED_KEYを使用しています。 addRowメソッドはこのオプションを持っていますか? –

0

また、slq/ucanaccessを使用する必要がある場合は、beginの接続でsetAutocommit(false)を呼び出し、各200/300レコードをコミットする必要があります。パフォーマンスは劇的に向上します(約99%)。

+0

各200/200レコードをコミットする方法は? –

+0

ちょうどカウントを行い、カウンタがすでに200個のレコードを挿入したと言われた場合にのみ、接続上のコミットを呼び出す... – jamadei

関連する問題