2012-04-16 88 views
6

我正在嘗試使用JDBC編寫一個數據庫獨立應用程序。我現在需要一種方法從某個表中獲取前N個條目。我看到JDBC中有一個setMaxRows方法,但我不習慣使用它,因爲我害怕數據庫將推出所有結果,只有JDBC驅動程序會減少結果。如果我需要排在十億行的表中前5名的結果,這將打破我的脖子(該表有一個可用的索引)。JDBC setMaxRows數據庫使用情況

編寫特殊的SQL語句爲每一種數據庫是不是很漂亮,但會讓數據庫做聰明的查詢計劃,並停止獲取超過必要的結果。

我可以依靠setMaxRows告訴數據庫到不行到多少?

我猜我不能依靠在希望的方式這個工作的最壞情況。我最感興趣的是Postgres 9.1和Oracle 11.2,所以如果有人對這些數據庫有經驗,請繼續前進。

+2

好問題。 javadoc說:「設置由Statement對象生成的任何ResultSet對象可以包含的最大行數限制爲給定數量,如果超出限制,超出的行將自動丟棄。」我讀到它的方式意味着JDBC驅動程序可以完成這項工作。我懷疑它的JDBC實現依賴。 – 2012-04-16 14:05:41

回答

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

這可能/可能會殺死你行的十億(S)的事情是在你的查詢(很有可能)ORDER BY條款。如果這個訂單不能使用索引建立,那麼。 。 。它會打破你的脖子:)

我不會依賴於這裏的jdbc驅動程序。正如之前的評論所暗示的,它不清楚它究竟做了什麼(看着不同的rdbms)。

如果您對您的查詢的速度而言,你可以使用LIMIT條款也是如此。如果您使用LIMIT,則至少可以確保它已傳遞到數據庫服務器。

編輯:對不起,我不知道Oracle不支持LIMIT

1

在直接回答您關於PostgreSQL 9.1的問題時:是的,JDBC驅動程序會告訴服務器停止生成超出您設置的行。

正如其他人所指出的,根據索引和所選計劃,服務器可能會掃描大量的行以找到您想要的五個行。正確的服務器配置可以幫助準確地模擬成本以防止出現這種情況,但是如果價值分佈不尋常,則可能需要引入和優化障礙(如與CTE一樣)來強制規劃者制定一個良好的計劃。