SELECT (ctid::text::point)[0]::bigint AS page_number FROM t;
তোমার বেহালার আমার সমাধান সঙ্গে।
@ বিএমএ ইতিমধ্যে একটি মন্তব্যে অনুরূপ কিছু ইঙ্গিত দিয়েছিল। এখানে একটি ...
প্রকারের জন্য যুক্তিযুক্ত
ctid
টাইপ tid
(টিপল শনাক্তকারী), ItemPointer
সি কোডে বলা হয়। প্রতি ডকুমেন্টেশন:
এটি সিস্টেম কলামের ডেটা ধরণ ctid
। একটি টিপল আইডি একটি জুড়ি ( ব্লক নম্বর , ব্লকের মধ্যে টিপল সূচক ) যা তার সারণির অভ্যন্তরে সারিটির শারীরিক অবস্থান চিহ্নিত করে।
বোল্ড জোর আমার। এবং:
( ItemPointer
, এছাড়াও হিসাবে পরিচিত CTID
)
একটি ব্লক স্ট্যান্ডার্ড ইনস্টলেশনগুলিতে 8 কেবি । সর্বাধিক সারণির আকার 32 টিবি । এটি যৌক্তিকভাবে অনুসরণ করে যে ব্লক সংখ্যায় অবশ্যই কমপক্ষে সর্বোচ্চ থাকতে হবে (@ ড্যানিয়েলের মন্তব্য অনুসারে গণনা স্থির করা):
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
। পোস্টগ্রিসের প্রতিটি কিছুর জন্য একটি পাঠ্য উপস্থাপনা রয়েছে :
আর একটি গুরুত্বপূর্ণ ব্যতিক্রম হ'ল "স্বয়ংক্রিয় আই / ও রূপান্তর কাস্ট", যা পাঠ্য বা অন্যান্য স্ট্রিংয়ের ধরণে বা রূপান্তর করতে কোনও ডেটা টাইপের নিজস্ব আই / ও ফাংশন ব্যবহার করে সম্পাদিত হয় সেগুলিতে স্পষ্টভাবে প্রতিনিধিত্ব করা হয় না
pg_cast
।
পাঠ্যের উপস্থাপনাটি একটি বিন্দুর সাথে মেলে যা দুটি float8
সংখ্যা নিয়ে গঠিত , castালাই নিখরচায়।
আপনি সূচক 0 কাস্ট সঙ্গে একটি বিন্দু প্রথম সংখ্যা অ্যাক্সেস করতে পারেন bigint
। Voila।
কর্মক্ষমতা
আমি আপনার আসল সহ: মনে মনে আসা কয়েকটি বিকল্প অভিব্যক্তিগুলির উপর 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
।
এর সংক্ষিপ্তসার: কাস্টিং স্ট্রিং ম্যানিপুলেশনের চেয়ে দ্রুত হতে থাকে। নিয়মিত প্রকাশগুলি ব্যয়বহুল। উপরের সমাধানটি সবচেয়ে সংক্ষিপ্ত এবং দ্রুততম।