সমস্যাটি
এখানে pgsql.general এ একটি খুব অনুরূপ কেস নিয়ে আলোচনা করা হয়েছে । এটি বি-ট্রি সূচকের সীমাবদ্ধতার বিষয়ে, তবে এটি সব একই কারণ একটি জিআইএন সূচক অভ্যন্তরীণভাবে কীগুলির জন্য একটি বি-ট্রি সূচক ব্যবহার করে এবং তাই কী আকারের জন্য একই সীমাবদ্ধতায় চলে যায় ( একটি সরল বি-ট্রিতে আইটেমের আকারের পরিবর্তে) সূচক)।
আমি জিআইএন সূচক বাস্তবায়ন সম্পর্কে ম্যানুয়ালটি উদ্ধৃত করেছি :
অভ্যন্তরীণভাবে, একটি জিআইএন সূচীতে একটি বি-ট্রি সূচক থাকে যা চাবিগুলির উপরে নির্মিত হয়, যেখানে প্রতিটি কী এক বা একাধিক সূচকযুক্ত আইটেমের উপাদান
যে কোনও উপায়ে, আপনার কলামে কমপক্ষে একটি অ্যারে এলিমেন্টdata
ইনডেক্স করা যায় না। এটি যদি কেবলমাত্র একক শৌখিন মান বা কোনও ধরণের দুর্ঘটনা হয় তবে আপনি মানটি কেটে ফেলতে এবং এটি দিয়ে কাজ করতে সক্ষম হতে পারেন।
নিম্নলিখিত ডেমোটির উদ্দেশ্যে আমি অন্যথায় ধরে নেব: অ্যারেতে প্রচুর দীর্ঘ পাঠ্য মান।
সহজ সমাধান
আপনি হ্যাশ মানdata
অনুসারে আপনার অ্যারেতে উপাদানগুলি প্রতিস্থাপন করতে পারেন । এবং একই হ্যাশ ফাংশনটির মাধ্যমে লুক-আপ মানগুলি প্রেরণ করুন। অবশ্যই আপনি সম্ভবত নিজের মূলগুলি কোথাও কোথাও সঞ্চয় করতে চান। এটির সাথে সাথে, আমরা প্রায় আমার দ্বিতীয় রূপটিতে পৌঁছেছি ...
উন্নত সমাধান
আপনি serial
সারোগেট প্রাথমিক কী হিসাবে কার্যকরভাবে কলাম সহ অ্যারের উপাদানগুলির জন্য একটি চেহারা সারণী তৈরি করতে পারেন (কার্যকরভাবে একটি মূল ধরণের হ্যাশ মান) - যা জড়িত উপাদানগুলির মানগুলি অনন্য না হলে এটি আরও আকর্ষণীয়:
CREATE TABLE elem (
elem_id serial NOT NULL PRIMARY KEY
, elem text UNIQUE NOT NULL
);
যেহেতু আমরা সন্ধান করতে চাই elem
, আমরা একটি সূচক যুক্ত করি - তবে লম্বা পাঠ্যের প্রথম প্রথম 10 টি অক্ষর সহ এবার একটি অভিব্যক্তিতে একটি সূচক । বেশিরভাগ ক্ষেত্রে অনুসন্ধানকে এক বা কয়েকটি হিটকে সংকীর্ণ করতে যথেষ্ট হওয়া উচিত। আপনার ডেটা বিতরণে আকারটি মানিয়ে নিন। অথবা আরও পরিশীলিত হ্যাশ ফাংশন ব্যবহার করুন।
CREATE INDEX elem_elem_left10_idx ON elem(left(elem,10));
আপনার কলামটি data
তখন ধরণের হবে int[]
। আমি টেবিলটির নতুন নামকরণ করেছি এবং আপনার উদাহরণে data
থাকা অশুচি থেকে মুক্তি পেয়েছি varchar(50)
:
CREATE TEMP TABLE data(
data_id serial PRIMARY KEY
, data int[]
);
প্রতিটি অ্যারে উপাদান data
একটি উল্লেখ করে elem.elem_id
। এই মুহুর্তে, আপনি অ্যারে কলামটি একটি এন: এম টেবিলের সাথে প্রতিস্থাপনের বিষয়ে বিবেচনা করতে পারেন, যার ফলে আপনার স্কিমাটি স্বাভাবিক করা এবং পোস্টগ্রিসকে রেফারেন্সিয়াল অখণ্ডতা প্রয়োগ করার অনুমতি দেওয়া হবে। সূচক এবং সাধারণ পরিচালনা সহজ হয়ে যায় ...
তবে, কার্য সম্পাদনের কারণে, int[]
একটি জিআইএন সূচকের সাথে সংযুক্ত কলামটি আরও ভাল হতে পারে। স্টোরেজ আকার অনেক ছোট। এই ক্ষেত্রে আমাদের জিআইএন সূচক প্রয়োজন:
CREATE INDEX data_data_gin_idx ON data USING GIN (data);
এখন, প্রতিটি চাবি জিন সূচক (= অ্যারের উপাদান) একজন হয় integer
একটি লম্বাটে পরিবর্তে text
। বিভিন্ন আকারের সূচি সূচকটি আরও ছোট হবে, ফলস্বরূপ অনুসন্ধানগুলি আরও দ্রুত হবে।
নেতিবাচকতা: আপনি প্রকৃতপক্ষে কোনও অনুসন্ধান চালানোর আগে আপনাকে elem_id
টেবিল থেকে সন্ধান করতে হবে elem
। আমার সদ্য চালু হওয়া ফাংশনাল ইনডেক্স ব্যবহার elem_elem_left10_idx
করা এটি খুব দ্রুত হবে।
আপনি একটি সাধারণ ক্যোয়ারিতে এটি সব করতে পারেন :
SELECT d.*, e.*
FROM elem e
JOIN data d ON ARRAY[e.elem_id] <@ d.data
WHERE left(e.elem, 10) = left('word1234word', 10) -- match index condition
AND e.elem = 'word1234word'; -- need to recheck, functional index is lossy
আপনি এক্সটেনশনে আগ্রহী হতে পারেন intarray
, এটি অতিরিক্ত অপারেটর এবং অপারেটর ক্লাস সরবরাহ করে।
data
এই ব্লগ পোস্টে প্রদর্শিত ট্যাগগুলির মতো ট্যাগগুলির একটি তালিকা থাকতে পারে ? যদি এটি হয় তবে আপনার জন্য আমার আরও ভাল সমাধান হতে পারে।