6

我正在尝试使用 JDBC 编写一个独立于数据库的应用程序。我现在需要一种方法来从某个表中获取前 N 个条目。看到setMaxRowsJDBC里面有一个方法,但是我用起来不太舒服,因为我怕数据库把所有结果都压出来,只有JDBC驱动才会减少结果。如果我需要一个有十亿行的表中的前 5 个结果,这将打破我的脖子(该表有一个可用的索引)。

为每种数据库编写特殊的 SQL 语句不是很好,但会让数据库进行巧妙的查询计划并停止获取不必要的结果。

我可以依靠setMaxRows告诉数据库不能工作吗?

我想在最坏的情况下,我不能以希望的方式依赖这种工作。我对 Postgres 9.1 和 Oracle 11.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 驱动程序将告诉服务器停止生成超出您设置的行。

正如其他人指出的那样,根据索引和选择的计划,服务器可能会扫描大量行以找到您想要的五个。适当的服务器配置可以帮助准确地建模成本以防止这种情况发生,但如果价值分布不寻常,您可能需要引入和优化障碍(如 CTE)来强制规划者制定一个好的计划。

于 2012-04-16T14:47:10.967 回答
1

可能/可能会用数十亿行杀死您的是查询中的(极有可能)ORDER BY子句。如果无法使用索引建立此订单,则 . . . 它会折断你的脖子:)

我不会依赖这里的 jdbc 驱动程序。正如先前的评论所暗示的,目前尚不清楚它的真正作用(查看不同的 rdbms)。

如果您担心查询的速度,您也可以使用LIMIT子句。如果您使用LIMIT,您至少可以确保它已传递到数据库服务器。

编辑:对不起,我不知道 Oracle 不支持LIMIT.

于 2012-04-16T14:12:48.043 回答