तो यह पता चला है कि समस्या की जड़ यह है कि डिफ़ॉल्ट रूप से, Postgres, "autoCommit" मोड में शुरू होता है और यह भी/कर्सर का उपयोग करता है डेटा के माध्यम से "पृष्ठ" करने में सक्षम होने की जरूरत है (पूर्व: पहले 10K पढ़ नतीजे, फिर अगला, फिर अगला), हालांकि कर्सर केवल लेनदेन के भीतर ही मौजूद हो सकते हैं। तो डिफॉल्ट सभी पंक्तियों को हमेशा रैम में पढ़ना है, और फिर अपने प्रोग्राम को "पहली परिणाम पंक्ति, फिर दूसरा" प्रसंस्करण शुरू करने की अनुमति देता है, दो कारणों से, यह लेनदेन में नहीं है (इसलिए कर्सर काम न करें), और एक fetch आकार भी सेट नहीं किया गया है।
तो psql
कमांड लाइन टूल प्रश्नों के लिए बैच प्रतिक्रिया (अपने FETCH_COUNT
सेटिंग) को प्राप्त होता है, एक अल्पकालिक लेन-देन के भीतर अपनी चुनिंदा प्रश्नों "रैप" (यदि किसी लेन-देन अभी तक खुला नहीं है), तो वह यह है कि कर्सर काम कर सकते हैं। भले ही आप राम को बचाने के लिए की जरूरत नहीं है
static void readLargeQueryInChunksJdbcWay(Connection conn, String originalQuery, int fetchCount, ConsumerWithException<ResultSet, SQLException> consumer) throws SQLException {
boolean originalAutoCommit = conn.getAutoCommit();
if (originalAutoCommit) {
conn.setAutoCommit(false); // start temp transaction
}
try (Statement statement = conn.createStatement()) {
statement.setFetchSize(fetchCount);
ResultSet rs = statement.executeQuery(originalQuery);
while (rs.next()) {
consumer.accept(rs); // or just do you work here
}
} finally {
if (originalAutoCommit) {
conn.setAutoCommit(true); // reset it, also ends (commits) temp transaction
}
}
}
@FunctionalInterface
public interface ConsumerWithException<T, E extends Exception> {
void accept(T t) throws E;
}
यह कम रैम की आवश्यकता होती है के लाभ देता है, और, मेरे परिणामों में, कुल मिलाकर तेजी से चलाने के लिए लग रहा था,: आप JDBC के साथ भी ऐसा ही कुछ कर सकते हैं। अजीब। यह लाभ भी देता है कि पहली पंक्ति की आपकी प्रसंस्करण "तेज़ी से शुरू होती है" (क्योंकि यह एक समय में एक पृष्ठ को संसाधित करती है)।
और यहाँ कैसे "कच्चे postgres कर्सर" जिस तरह से यह करने के लिए, पूर्ण डेमो code के साथ साथ, हालांकि मेरे प्रयोगों में यह JDBC तरह से लग रहा था है, ऊपर, थोड़ा जो भी कारण के लिए तेजी से किया गया था।
एक और विकल्प autoCommit
मोड बंद होना होगा, हालांकि आपको अभी भी प्रत्येक नए स्टेटमेंट के लिए मैन्युअल रूप से एक fetchSize निर्दिष्ट करना होगा (या आप URL स्ट्रिंग में डिफ़ॉल्ट फ़ेच आकार सेट कर सकते हैं)।
दूसरा लिंक काम नहीं कर रहा है ... – snorbi
इसे आजमाएं: http://jdbc.postgresql.org//documentation/head/query।एचटीएमएल # fetchsize-example –