ধীরগতির কোয়েরির সমস্যা সমাধান করতে, কোয়েরি এক্সপ্লেইন (Query Explain) ব্যবহার করে কোয়েরি এক্সিকিউশন প্ল্যান এবং রানটাইম এক্সিকিউশন প্রোফাইল সংগ্রহ করুন। এক্সিকিউশন প্রোফাইলের উপর নির্ভর করে কোয়েরির পারফরম্যান্স অপ্টিমাইজ করার জন্য আপনি যে পদক্ষেপগুলো নিতে পারেন, তা নিম্নলিখিত বিভাগে বর্ণনা করা হয়েছে:
ফলাফলের সংখ্যা সীমিত করুন
কোয়েরিটি অনেকগুলো ডকুমেন্ট ফেরত দিচ্ছে কিনা তা শনাক্ত করতে এক্সিকিউশন ট্রি-তে থাকা 'records returned' ফিল্ডটি ব্যবহার করুন। $limit ক্লজটি ব্যবহার করে ফেরত আসা ডকুমেন্টের সংখ্যা সীমিত করার কথা বিবেচনা করুন। এটি নেটওয়ার্কের মাধ্যমে ক্লায়েন্টদের কাছে ফলাফল ফেরত পাঠানোর সময় সেগুলোর সিরিয়ালাইজড বাইট সাইজ কমিয়ে দেয়। যেসব ক্ষেত্রে Limit নোডের আগে একটি MajorSort নোড থাকে, সেখানে কোয়েরি ইঞ্জিন Limit এবং MajorSort নোড দুটিকে একত্রিত করতে পারে এবং একটি সম্পূর্ণ ইন-মেমরি ম্যাটেরিয়ালাইজেশন ও সর্টের পরিবর্তে একটি TopN সর্ট ব্যবহার করে, যা কোয়েরিটির জন্য প্রয়োজনীয় মেমরি কমিয়ে দেয়।
ফলাফল ডকুমেন্টের আকার সীমিত করুন
অপ্রয়োজনীয় ফিল্ড ফেচ করা এড়াতে $project ক্লজ ব্যবহার করে ফেরত আসা ডকুমেন্টের আকার সীমিত করার কথা বিবেচনা করুন। এটি অন্তর্বর্তী ফলাফল প্রক্রিয়াকরণের কম্পিউট ও মেমরি খরচ এবং নেটওয়ার্কের মাধ্যমে ক্লায়েন্টদের কাছে ফেরত পাঠানো ফলাফলের সিরিয়ালাইজড বাইট সাইজ কমাতে সাহায্য করে। যেসব ক্ষেত্রে কোয়েরিতে উল্লেখিত সমস্ত ফিল্ড একটি সাধারণ ইনডেক্স (মাল্টি-কি নয়) দ্বারা অন্তর্ভুক্ত থাকে, সেখানে এটি কোয়েরিটিকে ইনডেক্স স্ক্যানের আওতায় সম্পূর্ণভাবে আসতে দেয়, ফলে প্রাইমারি স্টোরেজ থেকে ডকুমেন্ট ফেচ করার প্রয়োজন হয় না।
সূচক ব্যবহার করুন
ইনডেক্সগুলো সেট আপ ও অপ্টিমাইজ করতে নিম্নলিখিত নির্দেশাবলী ব্যবহার করুন।
কোয়েরিটি ইনডেক্স ব্যবহার করছে কিনা তা শনাক্ত করুন।
এক্সিকিউশন ট্রি-এর লিফ নোডগুলো পরীক্ষা করে আপনি শনাক্ত করতে পারেন যে কোয়েরিটি কোনো ইনডেক্স ব্যবহার করছে কিনা। যদি এক্সিকিউশন ট্রি-এর লিফ নোডটি একটি TableScan নোড হয়, তার মানে হলো কোয়েরিটি কোনো ইনডেক্স ব্যবহার করছে না এবং প্রাইমারি স্টোরেজ থেকে ডকুমেন্ট স্ক্যান করছে। যদি কোনো ইনডেক্স ব্যবহার করা হয়, তাহলে এক্সিকিউশন ট্রি-এর লিফ নোডটিতে ইনডেক্স আইডি এবং ইনডেক্সের ফিল্ডগুলো প্রদর্শিত হবে।
ব্যবহৃত সূচকটি অপ্টিমাইজ করা যায় কিনা তা শনাক্ত করুন।
একটি ইনডেক্স কোনো কোয়েরির জন্য তখনই কার্যকর হয়, যখন এটি প্রাইমারি স্টোরেজ থেকে কোয়েরি ইঞ্জিনকে প্রয়োজনীয় ডকুমেন্টের সংখ্যা কমাতে পারে অথবা এর ফিল্ডের ক্রমবিন্যাস কোয়েরিটির সর্ট (Sort) সংক্রান্ত চাহিদা পূরণ করতে পারে।
যদি কোনো কোয়েরির জন্য একটি ইনডেক্স ব্যবহার করা হয়, কিন্তু কোয়েরি ইঞ্জিন তারপরেও অনেক ডকুমেন্ট ফেচ করে এবং বাদ দিয়ে দেয়—যা একটি স্ক্যান নোডের মাধ্যমে অনেক রেকর্ড রিটার্ন করার পর একটি ফিল্টার নোডের মাধ্যমে অল্প কিছু রেকর্ড রিটার্ন করার মাধ্যমে বোঝা যায়—তবে এটি একটি লক্ষণ যে ইনডেক্স ব্যবহার করে পূরণ করা কোয়েরি প্রেডিকেটটি সিলেক্টিভ নয়। আরও উপযুক্ত ইনডেক্স তৈরি করতে, ‘ইনডেক্স তৈরি করুন’ দেখুন।
যদি কোনো কোয়েরির জন্য একটি নন-মাল্টিকি ইনডেক্স ব্যবহার করা হয়, কিন্তু কোয়েরি ইঞ্জিন তারপরেও রেজাল্ট সেটের ইন-মেমরি পুনর্বিন্যাস সম্পাদন করে, যা কোয়েরি এক্সিকিউশন ট্রিতে একটি MajorSort নোড দ্বারা চিহ্নিত হয়, তবে এটি একটি লক্ষণ যে ব্যবহৃত ইনডেক্সটি কোয়েরিটির সর্ট প্রয়োজনীয়তা পূরণের জন্য ব্যবহার করা যাবে না। আরও উপযুক্ত ইনডেক্স তৈরি করতে, পরবর্তী বিভাগটি দেখুন।
$lookup কোয়েরি অপ্টিমাইজ করা
আপনি from কালেকশনে ইনডেক্স যোগ করে $lookup কোয়েরি অপ্টিমাইজ করতে পারেন, যা পুরো কালেকশন স্ক্যান না করেই অপারেশনটিকে দক্ষতার সাথে মিলে যাওয়া ডকুমেন্ট খুঁজে পেতে সাহায্য করে।
localField এবং foreignField দিয়ে $lookup
আপনি যদি $lookup পর্যায়ে localField এবং foreignField অপশনগুলো ব্যবহার করেন, তাহলে from কালেকশনের foreignField এর উপর একটি ইনডেক্স তৈরি করুন।
নেস্টেড পাইপলাইন সহ $lookup
যদি আপনি $lookup স্টেজে $match স্টেজের সাথে pipeline অপশন ব্যবহার করেন, তাহলে সম্পূর্ণ টেবিল স্ক্যান এড়ানোর জন্য ফরেন কালেকশনের সাথে জড়িত ফিল্ডগুলোতে একটি ইনডেক্স তৈরি করুন:
- ফিল্টার সেম্যান্টিকস সহ
$matchস্টেজগুলির জন্য (উদাহরণস্বরূপ{$match: {a: true}}), ফরেন কালেকশন (a)-এর সাথে জড়িত ফিল্ডগুলির উপর একটি ইনডেক্স তৈরি করুন। - যেসব
$matchস্টেজে অ্যাগ্রিগেশন সেম্যান্টিকস কোনো ফিল্ডকে একটি ধ্রুবক মানের সাথে তুলনা করে (উদাহরণস্বরূপ{$match: {$expr: {$gt: [a, 10]}}}) অথবাletএ সংজ্ঞায়িত ফিল্ড এবং ভেরিয়েবলের মধ্যে ইকুয়ালিটি কম্প্যারিসন (eqবাin) ব্যবহার করা হয় (উদাহরণস্বরূপ{$match: {$expr: {$eq: [a, "$$a"]}}}), সেগুলোর ক্ষেত্রে ফরেন কালেকশনে সংশ্লিষ্ট ফিল্ডগুলোর উপর একটি ইনডেক্স তৈরি করুন। উল্লেখ্য যে, প্ল্যানিং-এর ক্ষেত্রে মাল্টিকি ইনডেক্স ব্যবহার করা হবে না।
ইনডেক্স তৈরি করুন
ইনডেক্স তৈরি করতে ইনডেক্স ম্যানেজমেন্ট ডকুমেন্টেশন অনুসরণ করুন। আপনার কোয়েরি যাতে ইনডেক্স ব্যবহার করতে পারে, তা নিশ্চিত করতে নিম্নলিখিত ক্রমে ফিল্ড সহ সাধারণ (মাল্টি-কি নয়) ইনডেক্স তৈরি করুন:
- যেসব ফিল্ড ইকুয়ালিটি অপারেটরে ব্যবহৃত হবে। বিভিন্ন কোয়েরিতে পুনঃব্যবহারের সম্ভাবনা সর্বাধিক করার জন্য, কোয়েরিগুলোর মধ্যে ইকুয়ালিটি অপারেটরে ফিল্ডগুলোর উপস্থিতির ক্রমহ্রাসমান অনুসারে সাজান।
- যেসব ফিল্ডের উপর ভিত্তি করে সর্টিং করা হবে (একই ক্রমে)।
- কোয়েরি কনস্ট্রেইন্ট সিলেক্টিভিটির অবরোহী ক্রম অনুসারে রেঞ্জ বা ইনইকুয়ালিটি অপারেটরে ব্যবহৃত ফিল্ডসমূহ।
- ইনডেক্সে কোয়েরির অংশ হিসেবে যে ফিল্ডগুলো ফেরত আসবে: ইনডেক্সে এই ধরনের ফিল্ড অন্তর্ভুক্ত করলে তা কোয়েরিটি সম্পন্ন করতে পারে এবং প্রাইমারি স্টোরেজ থেকে ডকুমেন্ট ফেচ করার প্রয়োজন এড়ানো যায়।
যেসব কোয়েরিতে অ্যারে ফিল্ড ফিল্টারিং ও সর্টিং করা হয়, সেগুলোর জন্য মাল্টিকি ইনডেক্স তৈরি করার কথা বিবেচনা করতে পারেন।
কোয়েরি হিন্ট ব্যবহার করুন
যদি আপনি কোয়েরিটির জন্য আরও উপযুক্ত কোনো ইনডেক্স তৈরি করে থাকেন কিন্তু কোয়েরি ইঞ্জিন সেই ইনডেক্সটি ব্যবহার না করে, তাহলে আপনি একটি কোয়েরি হিন্ট ব্যবহার করে কোয়েরি ইঞ্জিনের ইনডেক্স পছন্দকে অগ্রাহ্য করতে পারেন।
Query Explain দিয়ে চালানো কোনো কোয়েরির আউটপুট সম্পর্কে আরও তথ্যের জন্য, Query execution reference দেখুন।