Laravel-এ N+1 কুয়েরি শনাক্ত করা এবং অপ্রয়োজনীয় কুয়েরি নির্মূল করা
পারফরম্যান্স নিয়ে কাজ করা প্রায়শই বিরক্তিকর।
এটি সবসময় এমন কোনো বীরত্বগাথা নয় যেখানে আপনি ল্যাটেন্সি (latency) ৮০% কমিয়ে ফেলবেন। বেশিরভাগ দিন এটি মূলত পরিষ্কার-পরিচ্ছন্ন করার কাজ। আপনি এমন কিছু কুয়েরি খুঁজে পাবেন যা আপনি জানতেনই না যে আপনি চালাচ্ছেন। তারপর, আপনি সেগুলো মুছে ফেলবেন।
আপনার Laravel অ্যাপ যদি বড় হয়ে থাকে, তবে সম্ভবত আপনি এই তিনটি সমস্যার সম্মুখীন হচ্ছেন।
১. লুকানো N+1 কুয়েরি
আপনি যা দেখতে পাচ্ছেন না তা ঠিক করতে পারবেন না। আপনার লোকাল এনভায়রনমেন্টে beyondcode/laravel-query-detector এর মতো একটি টুল ব্যবহার করুন। এটি আপনাকে জানিয়ে দেবে যখন আপনি loop-and-lazy-load প্যাটার্ন ব্যবহার করবেন।
এটি প্রোডাকশনে (production) চালাবেন না। এটি অতিরিক্ত ওভারহেড (overhead) তৈরি করে। আপনার অ্যাপ যখন লোকাল বা টেস্টিং মোডে থাকবে, কেবল তখনই এটি রেজিস্টার করুন।
২. ইগার লোডিংয়ের (Eager Loading) অপচয়
মানুষ প্রায়ই with() যোগ করে N+1 সমস্যা সমাধান করার চেষ্টা করে। কিন্তু এটি একটি নতুন সমস্যা তৈরি করে। আপনি হয়তো এমন একটি রিলেশন ইগার-লোড (eager-load) করছেন যা আপনার ভিউ (view) আর ব্যবহার করছে না।
যদি কোনো রিডিজাইন কোনো টেবিল থেকে একটি কলাম সরিয়ে দেয়, তবে আপনাকে অবশ্যই আপনার কন্ট্রোলারে (controller) সংশ্লিষ্ট with() কলটি সরিয়ে ফেলতে হবে। আপনি এমন ডেটার জন্য খরচ করছেন যা আপনি ফেলে দিচ্ছেন।
প্রতিটি ইগার লোডকে একটি দাবির (claim) মতো বিবেচনা করুন। যদি আপনি ডেটাটি ব্যবহার না করেন, তবে সেই দাবিটি সরিয়ে ফেলুন।
৩. একই ডেটা বারবার গণনা করা
কিছু ভ্যালু পুরো রিকোয়েস্ট জুড়ে একই থাকে। আপনি যদি সেগুলো বারবার গণনা করেন, তবে আপনি CPU অপচয় করছেন। এটি ঠিক করতে memoization ব্যবহার করুন।
উদাহরণ:
protected ?string $defaultConnection = null;
public function getDefaultConnectionName(): string
{
return $this->defaultConnection ??= $this->resolveDefaultConnection();
}
??= অপারেটরটি ভ্যালুটি একবার গণনা করে এবং রিকোয়েস্টের বাকি অংশের জন্য এটি পুনরায় ব্যবহার করে।
৪. ড্যাশবোর্ড কুয়েরি ট্র্যাপ (Dashboard Query Traps)
ড্যাশবোর্ডগুলো প্রায়ই প্রতিটি কার্ডের জন্য আলাদা count() কুয়েরি চালায়। যদি আপনার ছয়টি কার্ড থাকে, তবে আপনি ছয়টি কুয়েরি চালাচ্ছেন।
এর পরিবর্তে এই দুটি কাজ করুন:
- আপনার কাউন্টগুলো গ্রুপ করুন। একটি টেবিলের সমস্ত টোটাল একটি মাত্র কুয়েরিতে নিয়ে আসুন।
- একটি শর্ট ক্যাশ (short cache) ব্যবহার করুন। ড্যাশবোর্ড স্ট্যাটাস প্রতি সেকেন্ডে লাইভ থাকার প্রয়োজন নেই। এগুলো পাঁচ মিনিটের জন্য ক্যাশ করে রাখুন।
একজন ভিজিটর কুয়েরির খরচ বহন করবেন। বাকি সবাই ক্যাশ করা ফলাফল পাবেন।
শেষ টিপস: রিগ্রেশন (Regressions) প্রতিরোধ করুন
যদি ডেভেলপাররা পরে আবার খারাপ কোড যোগ করে দেয়, তবে ক্লিনআপ ব্যর্থ হবে। আপনার কুয়েরি কাউন্ট অ্যাসার্ট (assert) করতে Pest ব্যবহার করুন। একটি পেজ সর্বোচ্চ কতগুলো কুয়েরি চালাতে পারবে তার একটি সীমা (ceiling) নির্ধারণ করে দিন। যদি কোনো ডেভেলপার N+1 যোগ করে, তবে টেস্টটি ফেইল করবে।
অপ্টিমাইজেশন মূলত হলো কিছু কিছু জিনিস সরিয়ে ফেলা। অব্যবহৃত লোডগুলো সরিয়ে ফেলুন। পুনরায় গণনা করা ভ্যালুগুলো সরিয়ে ফেলুন। অপ্রয়োজনীয় কুয়েরিগুলো সরিয়ে ফেলুন।
