2012-04-16 19 views
6

JDBCを使用してデータベースに依存しないアプリケーションを作成しようとしています。私は今、いくつかのテーブルから上位Nエントリをフェッチする方法が必要です。私はJDBCにsetMaxRowsメソッドがあるのを見ましたが、私はデータベースがすべての結果をプッシュして怖くて、JDBCドライバだけが結果を減らすので、それを使用するのが快適ではないと感じています。 10億行のテーブルでトップ5の結果が必要な場合、これは私の首を壊します(テーブルには利用可能なインデックスがあります)。JDBC setMaxRowsデータベースの使用

データベースの種類ごとに特殊なSQL文を書くことはあまりうまくはありませんが、データベースでクエリプランニングを賢明にし、必要以上に多くの結果を取得させます。

私はsetMaxRowsに頼ってデータベースにあまり働かないように指示できますか?

私は最悪の場合、私が期待したやり方でこれに頼ることはできないと思います。私は主にPostgres 9.1とOracle 11.2に興味があります。だから誰かがこれらのデータベースを使っている経験があれば、前進してください。

+2

良い質問です。 javadocは、 "このStatementオブジェクトによって生成されたResultSetオブジェクトが指定された数に含まれる最大行数の制限を設定します。制限を超えると、余分な行は静かに破棄されます。私がそれを読んだところ、それはJDBCドライバが作業を行うことができることを意味します。私はそのJDBC実装が依存していると考えています。 –

答えて

3

データベースは賢明なクエリプランニングを行い、より多くの結果を得るために、より多くの 結果を得ることができます。

あなたが使用している場合は

PostgreSQL

SELECT * FROM tbl ORDER BY col1 LIMIT 10; -- slow without index 

または:

SELECT * FROM tbl LIMIT 10;    -- fast even without index 

Oracle

SELECT * 
FROM (SELECT * FROM tbl ORDER BY col1 DESC) 
WHERE ROWNUM < 10; 

.. が返されるのは10行だけです。です。しかし、トップ10を選ぶ前に行をソートすると、すべて基本的に修飾行はとなり、ソートできるようになる前にとなります。

インデックスを一致させると、このオーバーヘッドを防ぐことができます。


あなたがわからない場合は、どのようなJDBCは、実際に、データベースサーバへの送信テストを実行し、データベースエンジンは受け取った文をログに記録しています。 PostgreSQLでは次のことができset in postgresql.conf

log_statement = all 

(およびリロード)サーバーに送信されたすべての文をログインします。テストの後にその設定をリセットするか、ログファイルが大きくなる可能性があります。

1

十億行であなたを殺してしまうかもしれないことは、クエリの中で(おそらく)ORDER BY句です。インデックスを使用してこの順序を確立できない場合。 。 。あなたの首を壊すでしょう:)

私はここではjdbcドライバに依存しません。以前のコメントは、実際に何が行われているのかがはっきりしないことを示唆しています(異なるrdbmsを見て)。

クエリの速度が懸念される場合は、LIMIT句を使用することもできます。LIMITを使用する場合は、少なくともそれがDBサーバーに渡されていることを確認することができます。

編集:申し訳ありませんが、私はOracleはLIMITをサポートしていないことに気づいていませんでした。 PostgreSQLの9.1について、あなたの質問に直接答えて

1

:はい、JDBCドライバが設定したものを超えた行の発生を停止するサーバーを教えてくれます。

他の人がインデックスに応じて、指摘されていると計画が選ばれたように、サーバは、あなたが望む5を見つけるために、大量の行をスキャンすることがあります。適切なサーバー構成は、これを防ぐためのコストを正確にモデル化するのに役立ちますが、値の分布が珍しい場合は、プランナーを強制して良い計画を作成するための障壁(CTEのような)を導入し最適化する必要があります。

関連する問題