5

12,000,000 以上のレコードを持つ innodb テーブルがあります。

SELECT *JDBC を使用して、このテーブルから2 つの方法を使用します。

Statement stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,java.sql.ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(Integer.MIN_VALUE);

この方法により、ドライバーは結果セットを行ごとにストリーミングでき、スキャンが完了するまでに 7 秒かかります。

Statement stmt =conn.createStatement();

ResultSet は完全に取得され、メモリに保存されます。この方法には 21 秒かかります。

結果セットを 1 行ずつフェッチする方が、完成した結果セットをクライアント メモリに取得するよりも速いのはなぜでしょうか。行ごとの方法は、ネットワーク転送に時間がかかるべきではありませんか?

4

1 に答える 1

1

OPに関する私のコメントを拡張するだけです

これはメモリの問題である可能性が最も高く、クライアントに大量の RAM がない限り、12m の結果をメモリに読み込むとページングが発生する可能性があります。ディスクのスラッシングを開始するとすぐに、パフォーマンスが大幅に低下します。RAM を増やし始めた場合、JVM は 32G を超えるアドレスに対処する方法にいくつかの癖があることに注意してください (64 ビット ポインターに切り替えます)。あなたのコードがどのように書かれているかについて。

物事を大局的に見ると、現在、elasticsearch を使用して、最大 6,000 万のドキュメントのインデックスを作成しています。確かに、インデックスやキャッシュなどを処理しているため、メモリの使用量はより複雑になりますが、パフォーマンスの高い応答を得るために 16G 未満の RAM を割り当てることは考えていません。非常に大きなレコード セットのために、シャードあたり 100G を超えるデータを使用している人に会ったことがあります。

于 2012-11-16T12:28:07.377 に答える