0

データベースに多くの行があり、処理する必要がありますが、メモリの制限により、すべてのデータをメモリに取得できません。

現時点では、LIMITとOFFSETを使用してデータを取得し、指定された間隔でデータを取得しています。

データベース内のテーブルからすべてのデータを取得するためのより高速な方法か、別の方法があるかを知りたいです。フィルタは適用されず、すべての行が処理されます。

4

2 に答える 2

5
SELECT * FROM table ORDER BY column

テーブル全体を RAM に吸い込む理由はありません。カーソルを開いて読み取りを開始するだけです。フェッチサイズなどでゲームをプレイできますが、行を処理している間、DB は喜んでその場所を維持します。

補遺:

わかりました。Java を使用している場合は、問題の内容がよくわかります。

まず、Java を使用しているだけで、カーソルを使用しています。これは基本的に、Java での ResultSet と同じです。一部の ResultSet は他のものより柔軟性がありますが、99% はシンプルで、「next」を呼び出して各行を取得する ResultSet のみを転送します。

今あなたの問題について。

問題は特に Postgres JDBC ドライバーにあります。なぜ彼らがこれを行うのかはわかりませんが、おそらくそれは仕様であり、おそらくそれは別のものですが、それでも、Postgres には奇妙な特徴があります。つまり、Connection で autoCommit が true に設定されている場合、Postgres はいずれかの結果セット全体を吸い込むことを決定します。 execute メソッドまたは最初の next メソッド。どこにあるかはそれほど重要ではありませんが、膨大な数の行がある場合にのみ、適切な OOM 例外が発生します。役に立ちません。

これはあなたが見ているものとまったく同じである可能性があり、非常にイライラして混乱する可能性があることを理解しています.

ほとんどの接続のデフォルトは autoCommit = true です。代わりに、単純に autoCommit を false に設定してください。

Connection con = ...get Connection...
con.setAutoCommit(false);
PreparedStatement ps = con.prepareStatement("SELECT * FROM table ORDER BY columm");
ResultSet rs = ps.executeQuery();
while(rs.next()) {
    String col1 = rs.getString(1);
    ...and away you go here...
}
rs.close();
ps.close();
con.close();

例外処理が明確に欠如していることに注意してください。これは、読者の課題として残しておきます。

一度にメモリにフェッチされる行数をさらに制御したい場合は、次を使用できます。

ps.setFetchSize(numberOfRowsToFetch);

それをいじってみると、パフォーマンスが向上する可能性があります。

順序付けに関心がある場合は、ORDER BY で使用する列に適切なインデックスがあることを確認してください。

于 2011-07-19T17:56:28.097 に答える
1

あなたのコメントに基づいてJavaを使用しているのは明らかなので:

JDBC を使用している場合は、http: //download.oracle.com/javase/1.5.0/docs/api/java/sql/ResultSet.htmlを使用することをお勧めします。

Hibernate を使用している場合は、より複雑になります: http://docs.jboss.org/hibernate/core/3.3/reference/en/html/batch.html

于 2011-07-20T03:09:56.273 に答える