আপডেট: এসকিউএলফিডেলে সমস্ত 5 টি প্রশ্নের 100K সারি (এবং 2 পৃথক কেস, একটিতে কয়েকটি (25) স্বতন্ত্র মান এবং অন্যটি প্রচুর (25K মান) এর সাথে পরীক্ষিত।
একটি খুব সাধারণ জিজ্ঞাসা ব্যবহার করা হবে UNION DISTINCT
। আমি মনে করি যে চারটি কলামের প্রত্যেকটির জন্য পৃথক সূচক থাকলে এটি সর্বাধিক দক্ষ হবে যদি পোস্টগ্র্রেস লুজ ইনডেক্স স্ক্যান অপ্টিমাইজেশন প্রয়োগ করে, তবে এটি চারটি কলামের প্রত্যেকটিতে পৃথক সূচী দিয়ে কার্যকর হবে। সুতরাং এই ক্যোয়ারি দক্ষ হবে না কারণ এটিতে টেবিলের 4 টি স্ক্যান প্রয়োজন (এবং কোনও সূচি ব্যবহৃত হয় না):
-- Query 1. (334 ms, 368ms)
SELECT a AS abcd FROM tablename
UNION -- means UNION DISTINCT
SELECT b FROM tablename
UNION
SELECT c FROM tablename
UNION
SELECT d FROM tablename ;
অন্যটি প্রথমে UNION ALL
এবং তারপরে ব্যবহার করতে হবে DISTINCT
। এর জন্য আরও 4 টি টেবিল স্ক্যান প্রয়োজন হবে (এবং সূচকের কোনও ব্যবহার নেই)। মানগুলি কম হলে খারাপ দক্ষতা হয় না এবং আরও মান সহ আমার (বিস্তৃত নয়) পরীক্ষায় দ্রুততম হয়:
-- Query 2. (87 ms, 117 ms)
SELECT DISTINCT a AS abcd
FROM
( SELECT a FROM tablename
UNION ALL
SELECT b FROM tablename
UNION ALL
SELECT c FROM tablename
UNION ALL
SELECT d FROM tablename
) AS x ;
অন্যান্য উত্তরগুলি অ্যারে ফাংশন বা LATERAL
সিনট্যাক্স ব্যবহার করে আরও বিকল্প সরবরাহ করেছে । জ্যাকের ক্যোয়ারিতে ( 187 ms, 261 ms
) যুক্তিসঙ্গত পারফরম্যান্স রয়েছে তবে অ্যান্ড্রিমের ক্যোয়ারী আরও দক্ষ ( 125 ms, 155 ms
) বলে মনে হচ্ছে । দুজনেই টেবিলের একটি ক্রমিক স্ক্যান করে এবং কোনও সূচক ব্যবহার করে না।
প্রকৃতপক্ষে জ্যাকের প্রশ্নের ফলাফলগুলি উপরে দেখানো থেকে কিছুটা ভাল (আমরা যদি সরিয়ে দিই order by
) এবং 4 টি অভ্যন্তরীণ অপসারণ করে distinct
এবং কেবল বাহ্যিকটিকে রেখে আরও উন্নত করা যায়।
অবশেষে, যদি - এবং কেবলমাত্র - 4 টি কলামের স্বতন্ত্র মান তুলনামূলকভাবে কম, আপনি WITH RECURSIVE
উপরের লুজ সূচক স্ক্যান পৃষ্ঠায় বর্ণিত হ্যাক / অপটিমাইজেশন ব্যবহার করতে পারেন এবং উল্লেখযোগ্য দ্রুত ফলাফলের সাথে সমস্ত 4 সূচক ব্যবহার করতে পারেন! একই 100K সারি এবং প্রায় 25 টি স্বতন্ত্র মানগুলি 4 কলামগুলিতে ছড়িয়ে পড়ে (কেবল 2 এমএসে চলে!) যখন 25K স্বতন্ত্র মানগুলির সাথে এটি 368 এমএসের সাথে সবচেয়ে ধীর হয়:
-- Query 3. (2 ms, 368ms)
WITH RECURSIVE
da AS (
SELECT min(a) AS n FROM observations
UNION ALL
SELECT (SELECT min(a) FROM observations
WHERE a > s.n)
FROM da AS s WHERE s.n IS NOT NULL ),
db AS (
SELECT min(b) AS n FROM observations
UNION ALL
SELECT (SELECT min(b) FROM observations
WHERE b > s.n)
FROM db AS s WHERE s.n IS NOT NULL ),
dc AS (
SELECT min(c) AS n FROM observations
UNION ALL
SELECT (SELECT min(c) FROM observations
WHERE c > s.n)
FROM dc AS s WHERE s.n IS NOT NULL ),
dd AS (
SELECT min(d) AS n FROM observations
UNION ALL
SELECT (SELECT min(d) FROM observations
WHERE d > s.n)
FROM db AS s WHERE s.n IS NOT NULL )
SELECT n
FROM
( TABLE da UNION
TABLE db UNION
TABLE dc UNION
TABLE dd
) AS x
WHERE n IS NOT NULL ;
SQLfiddle
সংক্ষিপ্তসার হিসাবে, যখন স্বতন্ত্র মানগুলি খুব কম হয়, তখন প্রচুর মূল্যবোধের সাথে পুনরুক্তিযুক্ত কোয়েরিটি সম্পূর্ণ বিজয়ী হয়, আমার ২ য় নম্বর, জ্যাকের (নীচে উন্নত সংস্করণ) এবং অ্যান্ডরিমের অনুসন্ধানগুলি সেরা পারফরমার।
দেরী সংযোজন, 1 ম ক্যোয়ারীর একটি প্রকরণ যা অতিরিক্ত স্বতন্ত্র অপারেশন সত্ত্বেও মূল 1 ম তুলনায় আরও ভাল সম্পাদন করে এবং 2 য় এর চেয়ে সামান্য খারাপ:
-- Query 1b. (85 ms, 149 ms)
SELECT DISTINCT a AS n FROM observations
UNION
SELECT DISTINCT b FROM observations
UNION
SELECT DISTINCT c FROM observations
UNION
SELECT DISTINCT d FROM observations ;
এবং জ্যাকের উন্নতি হয়েছে:
-- Query 4b. (104 ms, 128 ms)
select distinct unnest( array_agg(a)||
array_agg(b)||
array_agg(c)||
array_agg(d) )
from t ;
SELECT a FROM tablename UNION SELECT b FROM tablename UNION SELECT c FROM tablename UNION SELECT d FROM tablename ;
?