SELECT (ctid::text::point)[0]::bigint AS page_number FROM t;
मेरे समाधान के साथ आपकी बेला ।
@bma ने पहले ही एक टिप्पणी में कुछ इसी तरह का संकेत दिया। यहां है ...
प्रकार के लिए तर्क
ctid
प्रकार tid
(टुपल आइडेंटिफ़ायर) है, जिसे ItemPointer
C कोड में कहा जाता है। प्रति प्रलेखन:
यह सिस्टम कॉलम का डेटा प्रकार है ctid
। एक टपल आईडी एक जोड़ी ( ब्लॉक नंबर , ब्लॉक के भीतर टपल इंडेक्स ) है जो अपनी तालिका के भीतर पंक्ति के भौतिक स्थान की पहचान करती है।
बोल्ड जोर मेरा। तथा:
( ItemPointer
, के रूप में भी जाना जाता है CTID
)
मानक प्रतिष्ठानों में एक ब्लॉक 8 KB है। अधिकतम तालिका आकार 32 टीबी है । यह तार्किक रूप से इस प्रकार है कि ब्लॉक संख्या में कम से कम अधिकतम (@Daniel द्वारा टिप्पणी के अनुसार निर्धारित गणना) को समायोजित करना होगा :
SELECT (2^45 / 2^13)::int -- = 2^32 = 4294967294
जो एक अहस्ताक्षरित में फिट होगा integer
। आगे की जांच में मैंने सोर्स कोड में पाया कि ...
ब्लॉक क्रमिक रूप से गिने जाते हैं, 0 से 0xFFFFFFFE ।
बोल्ड जोर मेरा। जो पहले गणना की पुष्टि करता है:
SELECT 'xFFFFFFFE'::bit(32)::int8 -- max page number: 4294967294
पोस्टग्रेटेड हस्ताक्षरित पूर्णांक का उपयोग करता है और इसलिए यह एक छोटा है। मैं हस्ताक्षरित पूर्णांक को समायोजित करने के लिए पाठ प्रतिनिधित्व को स्थानांतरित कर दिया गया है या नहीं, फिर भी, मैं नीचे पिन नहीं कर सकता। जब तक कोई इसे साफ नहीं कर सकता, तब तक मैं वापस गिर जाऊंगा bigint
, जो किसी भी मामले में काम करता है।
कास्ट
नहीं है कोई पंजीकृत कलाकारों के लिए tid
Postgres 9.3 में प्रकार:
SELECT *
FROM pg_cast
WHERE castsource = 'tid'::regtype
OR casttarget = 'tid'::regtype;
castsource | casttarget | castfunc | castcontext | castmethod
------------+------------+----------+-------------+------------
(0 rows)
आप अभी भी डाल सकते हैं text
। Postgres में सब कुछ के लिए एक पाठ प्रतिनिधित्व है :
एक अन्य महत्वपूर्ण अपवाद यह है कि "स्वचालित I / O रूपांतरण कास्ट", उन लोगों ने डेटा प्रकार के अपने I / O फ़ंक्शन का उपयोग करके पाठ या अन्य स्ट्रिंग प्रकारों में कनवर्ट करने के लिए प्रदर्शन किया है, जिन्हें स्पष्ट रूप से प्रस्तुत नहीं किया गया है
pg_cast
।
पाठ निरूपण एक बिंदु से मेल खाता है, जिसमें दो float8
संख्याएँ होती हैं, वह कास्ट दोषरहित होता है।
आप सूचकांक 0. कास्ट के साथ बिंदु के पहले नंबर तक पहुंच सकते हैं bigint
। देखा।
प्रदर्शन
मैंने आपके मन में आए वैकल्पिक अभिव्यक्तियों के एक जोड़े पर 30k पंक्तियों (5 में से सर्वश्रेष्ठ) के साथ एक मेज पर एक त्वरित परीक्षण चलाया, जिसमें आपका नाम शामिल था:
SELECT (ctid::text::point)[0]::int -- 25 ms
,right(split_part(ctid::text, ',', 1), -1)::int -- 28 ms
,ltrim(split_part(ctid::text, ',', 1), '(')::int -- 29 ms
,(ctid::text::t_tid).page_number -- 31 ms
,(translate(ctid::text,'()', '{}')::int[])[1] -- 45 ms
,(replace(replace(ctid::text,'(','{'),')','}')::int[])[1] -- 51 ms
,substring(right(ctid::text, -1), '^\d+')::int -- 52 ms
,substring(ctid::text, '^\((\d+),')::int -- 143 ms
FROM tbl;
int
bigint
यहाँ के बजाय , परीक्षण के उद्देश्य के लिए ज्यादातर अप्रासंगिक है। मैंने दोहराया नहीं bigint
। @ जेक टिप्पणी की तरह उपयोगकर्ता परिभाषित समग्र प्रकार पर निर्माण
करने के लिए कलाकारों t_tid
।
इसका सार: कास्टिंग स्ट्रिंग हेरफेर की तुलना में अधिक तेज़ हो जाती है। नियमित भाव महंगे हैं। उपरोक्त समाधान सबसे छोटा और सबसे तेज़ है।