আমি উৎসুক ছিলাম. এবং যেমনটি আমরা সবাই জানি, কৌতূহল বিড়াল হত্যার খ্যাতি রয়েছে।
সুতরাং, একটি বিড়াল ত্বকের দ্রুততম উপায় কোনটি?
এই পরীক্ষার জন্য নির্ভুল বিড়াল চামড়ার পরিবেশ:
- পোস্টগ্রিএসকিউএল 9.0শালীন র্যাম এবং সেটিংস সহ ডেবিয়ান স্কিজে ।
- 6.000 শিক্ষার্থী, 24.000 ক্লাব সদস্যতা (বাস্তব জীবনের ডেটা সহ একই ডেটাবেস থেকে ডেপি অনুলিপি করা হয়েছে))
- প্রশ্নের নামকরণের স্কিমা থেকে সামান্য বিবর্তন:
student.id
হ'ল student.stud_id
এবং club.id
হ'লclub.club_id
এখানে।
- আমি এই থ্রেডে তাদের লেখকের নাম অনুসারে প্রশ্নের নামকরণ করেছি, যেখানে দুটি সূচক রয়েছে।
- আমি ক্যাশেটি জনপ্রিয় করার জন্য কয়েকবার সমস্ত অনুসন্ধান চালিয়েছি, তারপরে আমি বিশ্লেষণ বিশ্লেষণ সহ 5 টির মধ্যে সেরাটি বেছে নিয়েছি।
প্রাসঙ্গিক সূচীগুলি (সর্বোত্তম হওয়া উচিত - যতক্ষণ না আমাদের পূর্ব-জ্ঞানের অভাব রয়েছে যতক্ষণ না কোন ক্লাবগুলি অনুসন্ধান করা হবে):
ALTER TABLE student ADD CONSTRAINT student_pkey PRIMARY KEY(stud_id );
ALTER TABLE student_club ADD CONSTRAINT sc_pkey PRIMARY KEY(stud_id, club_id);
ALTER TABLE club ADD CONSTRAINT club_pkey PRIMARY KEY(club_id );
CREATE INDEX sc_club_id_idx ON student_club (club_id);
club_pkey
এখানে বেশিরভাগ প্রশ্নের দ্বারা প্রয়োজন হয় না।
প্রাথমিক কীগুলি পোস্টগ্রেএসকিউএলে স্বয়ংক্রিয়ভাবে অনন্য সূচি প্রয়োগ করে। পোস্টগ্র্রেএসকিউএল - তে বহু-কলাম সূচকের
এই জ্ঞাত অভাবের জন্য শেষ সূচকটি তৈরি করা হবে :
মাল্টিকোলামন বি-ট্রি সূচকটি ক্যোয়ারী শর্তগুলির সাথে ব্যবহার করা যেতে পারে যা সূচকের কলামগুলির কোনও উপসেট জড়িত, তবে শীর্ষস্থানীয় (বামতম) কলামগুলিতে সীমাবদ্ধতা থাকলে সূচকটি সবচেয়ে কার্যকর is
ফলাফল:
বিশ্লেষণ বিশ্লেষণের মোট রানটাইম।
1) মার্টিন 2: 44.594 এমএস
SELECT s.stud_id, s.name
FROM student s
JOIN student_club sc USING (stud_id)
WHERE sc.club_id IN (30, 50)
GROUP BY 1,2
HAVING COUNT(*) > 1;
2) এরউইন 1: 33.217 এমএস
SELECT s.stud_id, s.name
FROM student s
JOIN (
SELECT stud_id
FROM student_club
WHERE club_id IN (30, 50)
GROUP BY 1
HAVING COUNT(*) > 1
) sc USING (stud_id);
3) মার্টিন 1: 31.735 এমএস
SELECT s.stud_id, s.name
FROM student s
WHERE student_id IN (
SELECT student_id
FROM student_club
WHERE club_id = 30
INTERSECT
SELECT stud_id
FROM student_club
WHERE club_id = 50);
4) ডেরেক: 2.287 এমএস
SELECT s.stud_id, s.name
FROM student s
WHERE s.stud_id IN (SELECT stud_id FROM student_club WHERE club_id = 30)
AND s.stud_id IN (SELECT stud_id FROM student_club WHERE club_id = 50);
5) এরউইন 2: 2.181 এমএস
SELECT s.stud_id, s.name
FROM student s
WHERE EXISTS (SELECT * FROM student_club
WHERE stud_id = s.stud_id AND club_id = 30)
AND EXISTS (SELECT * FROM student_club
WHERE stud_id = s.stud_id AND club_id = 50);
6) শন: 2.043 এমএস
SELECT s.stud_id, s.name
FROM student s
JOIN student_club x ON s.stud_id = x.stud_id
JOIN student_club y ON s.stud_id = y.stud_id
WHERE x.club_id = 30
AND y.club_id = 50;
শেষ তিনটি বেশ একই রকম পারফর্ম করে। 4) এবং 5) একই ক্যোয়ারী পরিকল্পনার ফলাফল।
দেরী সংযোজন:
অভিনব এসকিউএল, তবে কর্মক্ষমতা ধরে রাখতে পারে না।
7) ইপারকিউব 1: 148.649 এমএস
SELECT s.stud_id, s.name
FROM student AS s
WHERE NOT EXISTS (
SELECT *
FROM club AS c
WHERE c.club_id IN (30, 50)
AND NOT EXISTS (
SELECT *
FROM student_club AS sc
WHERE sc.stud_id = s.stud_id
AND sc.club_id = c.club_id
)
);
8) ইপারকিউব 2: 147.497 এমএস
SELECT s.stud_id, s.name
FROM student AS s
WHERE NOT EXISTS (
SELECT *
FROM (
SELECT 30 AS club_id
UNION ALL
SELECT 50
) AS c
WHERE NOT EXISTS (
SELECT *
FROM student_club AS sc
WHERE sc.stud_id = s.stud_id
AND sc.club_id = c.club_id
)
);
প্রত্যাশিত হিসাবে, এই দুজন প্রায় একই রকম সম্পাদন করে। টেবিল স্ক্যানগুলির ক্যোয়ারী পরিকল্পনার ফলাফল, পরিকল্পনাকারী এখানে সূচকগুলি ব্যবহার করার কোনও উপায় খুঁজে পায় না।
9) ওয়াইল্ডপ্লাজার 1: 49.849 এমএস
WITH RECURSIVE two AS (
SELECT 1::int AS level
, stud_id
FROM student_club sc1
WHERE sc1.club_id = 30
UNION
SELECT two.level + 1 AS level
, sc2.stud_id
FROM student_club sc2
JOIN two USING (stud_id)
WHERE sc2.club_id = 50
AND two.level = 1
)
SELECT s.stud_id, s.student
FROM student s
JOIN two USING (studid)
WHERE two.level > 1;
অভিনব এসকিউএল, একটি সিটিইর জন্য শালীন পারফরম্যান্স। খুব বিদেশী ক্যোয়ারী প্ল্যান
আবার, 9.1 কীভাবে এটি পরিচালনা করে তা আকর্ষণীয় হবে। আমি শীঘ্রই এখানে ব্যবহৃত ডিবি ক্লাস্টারটি 9.1-এ উন্নীত করতে চলেছি। সম্ভবত আমি পুরো শেবাং পুনরায় চালু করব ...
10) ওয়াইল্ডপ্লাজার 2: 36.986 এমএস
WITH sc AS (
SELECT stud_id
FROM student_club
WHERE club_id IN (30,50)
GROUP BY stud_id
HAVING COUNT(*) > 1
)
SELECT s.*
FROM student s
JOIN sc USING (stud_id);
ক্যোরি 2 এর সিটিই ভেরিয়েন্ট)। আশ্চর্যজনকভাবে, এটি একই একই ডেটার সাথে কিছুটা পৃথক ক্যোয়ারী পরিকল্পনার ফলস্বরূপ। আমি student
সিক্যুয়াল স্ক্যান পেয়েছি , যেখানে সাব-কোয়েরি-ভেরিয়েন্ট সূচকটি ব্যবহার করে।
11) ইপারকিউব 3: 101.482 এমএস
আর দেরীতে সংযোজন এটি ইতিবাচকভাবে আশ্চর্যজনক, কতগুলি উপায় রয়েছে।
SELECT s.stud_id, s.student
FROM student s
JOIN student_club sc USING (stud_id)
WHERE sc.club_id = 10 -- member in 1st club ...
AND NOT EXISTS (
SELECT *
FROM (SELECT 14 AS club_id) AS c -- can't be excluded for missing the 2nd
WHERE NOT EXISTS (
SELECT *
FROM student_club AS d
WHERE d.stud_id = sc.stud_id
AND d.club_id = c.club_id
)
)
12) এরউইন 3: 2.377 এমএস
@ ইয়ারকিউবের 11) আসলে এই সহজ রূপটির কেবলমাত্র মন-মোড়ক বিপরীত পদ্ধতির, এটি এখনও অনুপস্থিত ছিল। শীর্ষ বিড়াল হিসাবে প্রায় দ্রুত সঞ্চালন।
SELECT s.*
FROM student s
JOIN student_club x USING (stud_id)
WHERE sc.club_id = 10 -- member in 1st club ...
AND EXISTS ( -- ... and membership in 2nd exists
SELECT *
FROM student_club AS y
WHERE y.stud_id = s.stud_id
AND y.club_id = 14
)
13) এরভিন 4: 2.375 এমএস
বিশ্বাস করা শক্ত, তবে এখানে আরও একটি আসল প্রকৃত রূপ। আমি দুটিরও বেশি সদস্যতার সম্ভাবনা দেখছি, তবে এটি শীর্ষ বিড়ালদের মধ্যেও রয়েছে মাত্র দুটি নিয়ে।
SELECT s.*
FROM student AS s
WHERE EXISTS (
SELECT *
FROM student_club AS x
JOIN student_club AS y USING (stud_id)
WHERE x.stud_id = s.stud_id
AND x.club_id = 14
AND y.club_id = 10
)
গতির সদস্য সংখ্যা গতিশীল
অন্য কথায়: ফিল্টার বিভিন্ন। এই প্রশ্নটি ঠিক দু'জনের জন্য জিজ্ঞাসা করেছিল ক্লাবের সদস্যতা । তবে অনেক ব্যবহারের ক্ষেত্রে বিভিন্ন সংখ্যার জন্য প্রস্তুত থাকতে হয়।
এই সম্পর্কিত উত্তর সম্পর্কে বিস্তারিত আলোচনা: