2009-09-23 13 views
8

मैं निम्नलिखित कोड का उपयोग कर रहाजावा जेडीबीसी setFetchSize को अनदेखा करता है?

st = connection.createStatement(
      ResultSet.CONCUR_READ_ONLY, 
      ResultSet.FETCH_FORWARD, 
      ResultSet.TYPE_FORWARD_ONLY 
      ); 
st.setFetchSize(1000); 
System.out.println("start query "); 
rs = st.executeQuery(queryString); 
System.out.println("done query"); 

क्वेरी (800k) बहुत सी पंक्तियाँ लौट सकते हैं और यह मुद्रण के बीच एक बड़ा समय (~ 2m) ले "क्वेरी शुरू" और "हो गया क्वेरी"। जब मैं अपनी क्वेरी में मैन्युअल रूप से "सीमा 10000" डालता हूं तो "प्रारंभ" और "पूर्ण" के बीच कोई समय नहीं होता है। परिणामों को संसाधित करने में समय लगता है, इसलिए मुझे लगता है कि यह कुल मिलाकर तेज़ है यदि यह डेटाबेस से 1k पंक्तियां प्राप्त करता है, उन प्रक्रियाओं को संसाधित करता है और जब यह पंक्तियों से बाहर हो रहा है तो यह पृष्ठभूमि में नए हो सकता है।

परिणामसेट.कॉनकुर_READ_ONLY आदि जहां मेरा आखिरी अनुमान है; क्या मैं कुछ भूल रहा हूँ?

+0

setFetchSize वास्तव में PostgreSQL ड्राइवर के साथ अच्छी तरह से काम करता है में पैरामीटर प्रदान करने का प्रयास करें, यह सिर्फ एक बहुत करता है आप इससे अपेक्षा करते हैं कि अलग-अलग चीज। मेरा जवाब देखें – Henning

+0

यह भी देखें https://stackoverflow.com/a/47517489/32453 – rogerdpack

उत्तर

2

यह (यह एक PostgreSQL 8.3 सर्वर है) अपने ड्राइवर पर निर्भर करेगा। डॉक्स से:

JDBC ड्राइवर पंक्तियों को डेटाबेस से दिलवाया जाना चाहिए की संख्या के रूप में एक संकेत देता है जब अधिक पंक्तियों की जरूरत है। निर्दिष्ट पंक्तियों की संख्या इस कथन का उपयोग करके केवल परिणाम सेट को प्रभावित करती है। यदि निर्दिष्ट मान शून्य है, तो संकेत को अनदेखा किया जाता है। डिफ़ॉल्ट मान शून्य है।

ध्यान दें कि यह "संकेत" कहता है - मैं इसका मतलब यह समझूंगा कि एक ड्राइवर अगर संकेत चाहता है तो संकेत को अनदेखा कर सकता है ... और ऐसा लगता है कि यह क्या हो रहा है।

+0

हाँ मैंने इसे पढ़ा लेकिन यह विश्वास नहीं कर सका कि जेडीबीसी + पोस्टग्रेएसक्यूएल इसे अनदेखा कर देगा, यह उम्र के आसपास है। – kresjer

+0

@kresjer: इसका पोस्टग्रेस्क्ल इसलिए आपको डीबी और जेडीबीसी ड्राइवरों के स्रोत तक पहुंच प्राप्त करनी चाहिए। आप इसका उपयोग यह पता लगाने के लिए कर सकते हैं कि वास्तव में क्या चल रहा है ... –

+0

एनबी जो पोस्टग्रेज़ (यदि ऑटोकॉमिट बंद हो गया है तो इतना ही काम कर रहा है) 0 को लाने का आकार स्पष्ट रूप से इसे "सब कुछ" डिफ़ॉल्ट रूप से कैश करता है (अनुमान है कि वे एक संकेत को "अनदेखा" कैसे समझते हैं) ऑरैकल डिफ़ॉल्ट रूप से 10 है http://docs.oracle.com/cd/A97335_02/apps.102/a83724/resltse5.htm – rogerdpack

20

मोड़ बंद ऑटो प्रतिबद्ध प्रयास करें:

// make sure autocommit is off 
connection.setAutoCommit(false); 

st = connection.createStatement(); 
st.setFetchSize(1000); 
System.out.println("start query "); 
rs = st.executeQuery(queryString); 
System.out.println("done query"); 

Reference

+1

बिल्कुल। setFetchSize PostCresSQL जेडीबीसी ड्राइवर के साथ ऑटो कॉमिट मोड में काम नहीं कर रहा है। –

+1

यह ध्यान देने योग्य है कि कनेक्शन कनेक्शन बंद करने से पहले आपको ऑटोोकॉमिट को वापस चालू करने की आवश्यकता है, यदि आप कनेक्शन पूलिंग का उपयोग कर रहे हैं, और ऐप के अन्य हिस्सों ऑटोोकॉमिट पर भरोसा करते हैं। अन्यथा जब आप स्पष्ट रूप से काम नहीं कर रहे हैं तो आप यादृच्छिक डेटा हानि के साथ समाप्त हो सकते हैं। –

+1

इस पोस्टग्रेएसक्यूएल जेडीबीसी प्रतिबंध पर अधिक जानकारी http://jdbc.postgresql.org/documentation/head/query.html#query-with-cursor पर मिल सकती है। – Alex

3

दो प्रश्नों पूरी तरह से अलग बातें करते हैं।

LIMIT खंड का उपयोग करना, परिणाम 10000 करने के लिए सेट के आकार को सीमित सेट करते समय लाने आकार नहीं है, यह बजाय चालक को एक संकेत करते हुए कहा कि कितने पंक्तियों एक समय पर लाने के लिए जब परिणाम सेट के माध्यम से पुनरावृत्ति देता है - जिसमें सभी 800k पंक्तियां शामिल हैं।

तो setFetchSize का उपयोग करते समय, डेटाबेस पूर्ण परिणाम सेट बनाता है, यही कारण है कि यह बहुत लंबा समय ले रहा है। स्पष्टता के लिए

संपादित करें: आकार लाने की स्थापना जब तक आप (जॉन की टिप्पणी देखें) परिणाम के माध्यम से पुनरावृति है, लेकिन एक बहुत छोटे से LIMIT के माध्यम से सेट परिणाम बनाने के लिए एक महान फर्क नहीं पड़ता कुछ नहीं करता है।

+0

लेकिन वह * परिणाम सेट के माध्यम से * पुनरावृत्ति नहीं कर रहा है। विचार यह है कि * जब आप परिणाम सेट के माध्यम से पुन: प्रयास करते हैं, आदर्श रूप से इसे नेटवर्क पर 1000 परिणाम प्राप्त करना चाहिए, तो आप उनको संसाधित कर सकते हैं, और जब आप 1001 पर पहुंच जाएंगे तो यह अगले 1000 आदि –

+0

लाएगा। गति में अंतर परिणाम सेट के differenr आकारों के कारण है, 10000 बनाम 800000. – Henning

2

मैंने देखा है कि API के उपयोग क्या जावाडोक द्वारा व्यक्त से अलग है:

इस आदेश

ResultSet.TYPE_FORWARD_ONLY, 
    ResultSet.CONCUR_READ_ONLY, 
    ResultSet.FETCH_FORWARD 
+1

इन 3 कुंजी, conn.setAutoCommit (झूठी) सेटिंग के साथ मेरे लिए चाल है – Peter

संबंधित मुद्दे