কেবল 400 টি স্টেশনের জন্য, এই ক্যোয়ারী ব্যাপকভাবে দ্রুত হবে:
SELECT s.station_id, l.submitted_at, l.level_sensor
FROM station s
CROSS JOIN LATERAL (
SELECT submitted_at, level_sensor
FROM station_logs
WHERE station_id = s.station_id
ORDER BY submitted_at DESC NULLS LAST
LIMIT 1
) l;
এখানে ডিবিফিডল
(এই ক্যোয়ারির জন্য পরিকল্পনাগুলির তুলনা, অ্যাবেলিস্টোর বিকল্প এবং আপনার মূল) তুলনা করুন)
EXPLAIN ANALYZEওপি দ্বারা সরবরাহিত ফলাফল :
নেস্টেড লুপ (ব্যয় = 0.56..356.65 সারি = 102 প্রস্থ = 20) (আসল সময় = 0.034..0.979 সারি = 98 লুপ = 1)
-> স্টেশনগুলিতে সিক স্ক্যান (ব্যয় = 0.00..3.02 সারি = 102 প্রস্থ = 4) (আসল সময় = 0.009..0.016 সারি = 102 লুপ = 1)
-> সীমা (খরচ = 0.56..3.45 সারি = 1 প্রস্থ = 16) (আসল সময় = 0.009..0.009 সারি = 1 লুপ = 102)
-> স্টেশন_লগগুলিতে স্টেশন_আইডি__ জমা দেওয়া_এট ব্যবহার করে সূচক স্ক্যান (দাম = 0.56..664062.38 সারি = 230223 প্রস্থ = 16) (আসল সময় = 0.009 $
সূচকের অবস্থা: (স্টেশন_আইডি = এস.আইডি)
পরিকল্পনার সময়: 0.542 এমএসফাঁসির
সময়: 1.013 এমএস - !!
শুধুমাত্র সূচক আপনি প্রয়োজন এক আপনার তৈরি করা হল: station_id__submitted_at। UNIQUEবাধ্যতা uniq_sid_satএছাড়াও পেশা আছে, মূলত। উভয়ই বজায় রাখা ডিস্কের জায়গার অপচয় এবং লেখার পারফরম্যান্সের মতো মনে হয়।
আমি যোগ NULLS LASTকরতে ORDER BYকারণ ক্যোয়ারীতে submitted_atসংজ্ঞায়িত করা হয় না NOT NULL। আদর্শভাবে, যদি প্রযোজ্য হয়! NOT NULLকলামে একটি সীমাবদ্ধতা যুক্ত করুন submitted_at, অতিরিক্ত সূচকটি ছেড়ে দিন NULLS LASTএবং ক্যোয়ারী থেকে সরিয়ে দিন ।
যদি submitted_atহতে পারে তবে আপনার বর্তমান সূচি এবং অনন্য বাধা উভয়ই প্রতিস্থাপন NULLকরতে এই UNIQUEসূচকটি তৈরি করুন :
CREATE UNIQUE INDEX station_logs_uni ON station_logs(station_id, submitted_at DESC NULLS LAST);
বিবেচনা:
এটি প্রাসঙ্গিক প্রতি এক সারি (সাধারণত পিকে) সহ একটি পৃথক টেবিলstation ধরে station_idনিচ্ছে - যা আপনার উভয় দিক দিয়েই হওয়া উচিত। আপনার যদি এটি না থাকে তবে এটি তৈরি করুন। আবার, এই আরসিটিই কৌশলটি দিয়ে খুব দ্রুত:
CREATE TABLE station AS
WITH RECURSIVE cte AS (
(
SELECT station_id
FROM station_logs
ORDER BY station_id
LIMIT 1
)
UNION ALL
SELECT l.station_id
FROM cte c
, LATERAL (
SELECT station_id
FROM station_logs
WHERE station_id > c.station_id
ORDER BY station_id
LIMIT 1
) l
)
TABLE cte;
আমি হ'ল ফিডেলেও এটি ব্যবহার করি। আপনি stationটেবিল ছাড়াই সরাসরি নিজের টাস্কটি সমাধান করতে অনুরূপ ক্যোয়ারী ব্যবহার করতে পারেন - যদি আপনি এটি তৈরির বিষয়ে নিশ্চিত হতে না পারেন তবে।
বিস্তারিত নির্দেশাবলী, ব্যাখ্যা এবং বিকল্পগুলি:
সূচক অনুকূলিত করুন
আপনার ক্যোয়ারী এখন খুব দ্রুত হওয়া উচিত। আপনার যদি এখনও পড়ার পারফরম্যান্সটিকে অপ্টিমাইজ করা প্রয়োজন ...
জোয়ানোলো মন্তব্য করেছে , কেবলমাত্র সূচি-কেবল স্ক্যানগুলিকেlevel_sensor অনুমতি দেওয়ার জন্য সূচীতে শেষ কলাম হিসাবে যুক্ত হওয়া অর্থপূর্ণ হতে পারে । কন: এটি সূচকে আরও বড় করে তোলে - যা এটি ব্যবহার করে সমস্ত প্রশ্নের জন্য সামান্য ব্যয় যুক্ত করে। প্রো: আপনি যদি সূচকটি কেবলমাত্র এটি থেকে স্ক্যান করেই পান তবে হাতে থাকা ক্যোয়ারিতে হিপ পৃষ্ঠাগুলি মোটেও দেখার দরকার নেই যা এটি প্রায় দ্বিগুণ দ্রুত করে তোলে। তবে এটি এখন খুব দ্রুত অনুসন্ধানের জন্য একটি অনিবার্য লাভ হতে পারে।
তবে , আমি আশা করি না যে এটি আপনার ক্ষেত্রে কাজ করবে for তুমি উল্লেখ করেছিলে:
... প্রতিদিন প্রায় 20k সারি station_id।
সাধারণত, এটি নিরবচ্ছিন্ন লেখার বোঝা (প্রতি station_id5 সেকেন্ডে 1 জন ) নির্দেশ করবে। এবং আপনি সর্বশেষ সারিতে আগ্রহী । সূচক-কেবলমাত্র স্ক্যানগুলি হ'ল পৃষ্ঠাগুলির জন্যই কাজ করে যা সমস্ত লেনদেনের জন্য দৃশ্যমান (দৃশ্যমান মানচিত্রে কিছুটা সেট করা আছে)। VACUUMলেখার বোঝাটি ধরে রাখতে আপনাকে টেবিলের জন্য অত্যন্ত আক্রমণাত্মক সেটিংস চালাতে হবে এবং এটি বেশিরভাগ সময় কাজ করবে না। যদি আমার অনুমানগুলি সঠিক হয় তবে কেবলমাত্র সূচি-স্ক্যানগুলি বাইরে চলে গেছে, সূচীতে যুক্ত করবেন নাlevel_sensor ।
ওহ, যদি আমার অনুমানগুলি ধরে থাকে এবং আপনার টেবিলটি খুব বড় আকার ধারণ করছে তবে একটি ব্রিন সূচক সাহায্য করতে পারে। সম্পর্কিত:
বা, আরও বেশি বিশেষজ্ঞ এবং আরও দক্ষ: কেবলমাত্র অপ্রাসঙ্গিক সারিগুলি কাটাতে সর্বশেষ সংযোজনগুলির একটি আংশিক সূচক:
CREATE INDEX station_id__submitted_at_recent_idx ON station_logs(station_id, submitted_at DESC NULLS LAST)
WHERE submitted_at > '2017-06-24 00:00';
এমন টাইমস্ট্যাম্প চয়ন করুন যার জন্য আপনি জানেন যে কম বয়সী সারিগুলি অবশ্যই বিদ্যমান। WHEREআপনাকে সমস্ত প্রশ্নের সাথে মিলে যাওয়ার শর্ত যুক্ত করতে হবে, যেমন:
...
WHERE station_id = s.station_id
AND submitted_at > '2017-06-24 00:00'
...
আপনাকে সময়ে সময়ে সূচি এবং ক্যোয়ারীটি মানিয়ে নিতে হবে।
আরও বিশদ সহ সম্পর্কিত উত্তর: