我正在尝试使用JDBC编写数据库独立应用程序。我现在需要一种从某些表中获取前N个条目的方法。我看到JDBC中有一个setMaxRows
方法,但我觉得使用它并不舒服,因为我害怕数据库会推出所有结果,只有JDBC驱动程序会减少结果。如果我需要在具有十亿行的表格中排名前五的结果,这将打破我的脖子(该表具有可用的索引)。
为每种类型的数据库编写特殊的SQL语句并不是很好,但是会让数据库做出巧妙的查询计划并停止获取超出必要的结果。
我可以依靠setMaxRows
告诉数据库不起作用吗?
我想在最糟糕的情况下,我不能依靠希望的方式工作。我最感兴趣的是Postgres 9.1和Oracle 11.2,所以如果有人有这些数据库的经验,请向前迈进。
答案 0 :(得分:3)
将让数据库进行巧妙的查询计划并停止提取更多内容 结果不必要。
如果您使用
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中,你可以set in postgresql.conf
:
log_statement = all
(并重新加载)以记录发送到服务器的所有语句。确保在测试后重置该设置,否则您的日志文件可能会变得很大。
答案 1 :(得分:1)
可能/可能会使用十亿行来杀死你的东西是查询中的(极有可能)ORDER BY
子句。如果使用索引无法建立此订单。 。 。它会打破你的脖子:)。
我不会在这里依赖jdbc驱动程序。正如之前的评论所暗示的那样,目前还不清楚它的真正作用(查看不同的rdbms)。
如果您担心查询速度,也可以使用LIMIT
子句。如果使用LIMIT
,至少可以确保它已传递到数据库服务器。
编辑:抱歉,我不知道Oracle不支持LIMIT
。
答案 2 :(得分:1)
直接回答有关PostgreSQL 9.1的问题:是的,JDBC驱动程序将告诉服务器停止生成超出您设置的行。
正如其他人所指出的那样,根据索引和所选择的计划,服务器可能会扫描非常多的行以找到您想要的五行。正确的服务器配置可以帮助准确地模拟成本以防止这种情况,但如果价值分配不常见,您可能需要引入和优化障碍(如CTE)来强制规划人员制定一个好的计划。