पोस्टग्रेएसक्यूएल में बड़ी तालिकाओं में पंक्तियों की गिनती धीमी गति से होती है। एक सटीक संख्या प्राप्त करने के लिए इसे MVCC की प्रकृति के कारण पंक्तियों की एक पूरी गणना करनी होती है । नाटकीय रूप से इसे गति देने का एक तरीका है यदि गिनती सही नहीं है जैसा कि आपके मामले में लगता है।
सटीक गणना प्राप्त करने के बजाय ( बड़ी तालिकाओं के साथ धीमी ):
SELECT count(*) AS exact_count FROM myschema.mytable;
आपको इस तरह का एक अत्यंत अनुमानित अनुमान है ( अत्यंत तेज़ ):
SELECT reltuples::bigint AS estimate FROM pg_class where relname='mytable';
अनुमान कितना करीब है यह इस बात पर निर्भर करता है कि आप ANALYZEपर्याप्त भाग लेते हैं। यह आमतौर पर बहुत करीब है। PostgreSQL Wiki FAQ
देखें ।
या गिनती (*) प्रदर्शन के लिए समर्पित विकी पेज ।
और भी बेहतर
PostgreSQL विकी में लेख है था थोड़ा लापरवाह । इसने इस संभावना को नजरअंदाज कर दिया कि एक डेटाबेस में एक ही नाम के कई टेबल हो सकते हैं - अलग-अलग स्कीमा में। उस के लिए खाते में:
SELECT c.reltuples::bigint AS estimate
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relname = 'mytable'
AND n.nspname = 'myschema'
या अभी भी बेहतर है
SELECT reltuples::bigint AS estimate
FROM pg_class
WHERE oid = 'myschema.mytable'::regclass;
तेज़, सरल, सुरक्षित, अधिक सुरुचिपूर्ण। ऑब्जेक्ट पहचानकर्ता प्रकार पर मैनुअल देखें ।
to_regclass('myschema.mytable')अमान्य तालिका नामों के अपवादों से बचने के लिए Postgres 9.4+ का उपयोग करें :
SELECT 100 * count(*) AS estimate FROM mytable TABLESAMPLE SYSTEM (1);
जैसे @a_horse ने टिप्पणी की , SELECTकमांड के लिए नया जोड़ा क्लॉज उपयोगी हो सकता है यदि आंकड़े pg_classकिसी कारण से पर्याप्त नहीं हैं। उदाहरण के लिए:
- नहीं
autovacuumचल रहा है।
- किसी बड़े के तुरंत बाद
INSERTया DELETE।
TEMPORARYतालिकाओं (जो द्वारा कवर नहीं हैं autovacuum)।
यह केवल ब्लॉक और यादृच्छिक पंक्तियों के चयन में एक यादृच्छिक n % ( 1उदाहरण में) को देखता है। एक बड़ा नमूना लागत को बढ़ाता है और त्रुटि को कम करता है, आपकी पिक। सटीकता अधिक कारकों पर निर्भर करती है:
- पंक्ति आकार का वितरण। यदि किसी दिए गए ब्लॉक में सामान्य पंक्तियों की तुलना में व्यापक पकड़ होती है, तो गिनती सामान्य से कम होती है आदि।
- मृत टुपल्स या
FILLFACTORप्रति ब्लॉक एक व्यस्त स्थान। यदि असमान रूप से तालिका में वितरित किया जाता है, तो अनुमान बंद हो सकता है।
- सामान्य दौर की त्रुटियां।
ज्यादातर मामलों में से अनुमान pg_classतेज और अधिक सटीक होगा।
वास्तविक प्रश्न का उत्तर
पहले, मुझे उस तालिका में पंक्तियों की संख्या जानने की आवश्यकता है, यदि कुल संख्या कुछ पूर्वनिर्धारित स्थिरांक से अधिक है,
और क्या यह ...
... इस समय यह संभव है कि गिनती मेरे निरंतर मूल्य को पार कर ले, यह गिनती को रोक देगा (और पंक्ति की संख्या अधिक होने की सूचना देने के लिए गिनती खत्म होने का इंतजार न करें)।
हाँ। आप इसके साथLIMIT एक उपश्रेणी का उपयोग कर सकते हैं :
SELECT count(*) FROM (SELECT 1 FROM token LIMIT 500000) t;
पोस्टग्रैज वास्तव में दी गई सीमा से परे गिनती करना बंद कर देता है, आपको n पंक्तियों (उदाहरण में 500000) के लिए एक सटीक और वर्तमान गणना मिलती है , और अन्यथा n । हालांकि, अनुमान के अनुसार तेजी से नहीं ।pg_class