6

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

あらゆる種類のデータベースに対して特別なSQLステートメントを作成することはあまり良いことではありませんが、データベースが巧妙なクエリプランニングを実行し、必要以上の結果のフェッチを停止できるようにします。

setMaxRowsデータベースにあまり機能しないように指示することに頼ることはできますか?

最悪の場合、私はこれが期待通りに機能することに頼ることができないと思います。私は主にPostgres9.1とOracle11.2に興味があるので、誰かがこれらのデータベースの経験がある場合は、前に進んでください。

4

3 に答える 3

3

データベースに巧妙なクエリプランニングを実行させ、必要以上の結果のフェッチを停止させます。

使用する場合

PostgreSQL

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

または:

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

オラクル

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

..その後、10行のみが返されます。ただし、上位10を選択する前に行を並べ替えると、基本的に修飾されているすべての行が読み取られてから並べ替えられます。

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


不明な場合は、JDBCが実際にデータベースサーバーに送信するものを確認し、テストを実行して、受信したステートメントをデータベースエンジンに記録させます。PostgreSQLでは、次のように設定postgresql.confできます。

log_statement = all

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

于 2012-04-16T14:11:38.847 に答える
1

PostgreSQL 9.1に関する質問への直接の回答:はい、JDBCドライバーは、設定した行を超える行の生成を停止するようにサーバーに指示します。

他の人が指摘しているように、インデックスと選択したプランによっては、サーバーが非常に多くの行をスキャンして、必要な5つを見つける場合があります。適切なサーバー構成は、これを防ぐためにコストを正確にモデル化するのに役立ちますが、値の分散が異常な場合は、プランナーに適切な計画を作成するように強制するために、最適化バリア(CTEなど)を導入する必要があります。

于 2012-04-16T14:47:10.967 に答える
1

ORDER BY数十億の行であなたを殺す可能性がある/かもしれないのは、クエリの(可能性が高い)句です。インデックスを使用してこの順序を確立できない場合は、。。。それはあなたの首を壊します:)

ここでは、jdbcドライバーに依存しません。以前のコメントが示唆しているように、それが実際に何をしているのかは不明です(さまざまなrdbmsを見てください)。

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

編集:申し訳ありませんが、Oracleがをサポートしていないことに気づいていませんでしLIMITた。

于 2012-04-16T14:12:48.043 に答える