Django ORM Queries অপ্টিমাইজ করা
Django ORM ডাটাবেসের কাজ সহজ করে তোলে। কিন্তু এটি একটি বিপদ লুকিয়ে রাখে। আপনি যদি সম্পর্কিত অবজেক্টগুলো (related objects) সঠিকভাবে ফেচ (fetch) না করেন, তবে আপনি N+1 query সমস্যার সৃষ্টি করতে পারেন।
এর মানে হলো, আপনি যদি ১০০টি পোস্ট ফেচ করেন, তবে আপনার অ্যাপ ১০১টি কুয়েরি চালাতে পারে। এটি আপনার অ্যাপের গতি কমিয়ে দেয় বা অ্যাপটিকে স্লো করে ফেলে।
এটি সমাধান করতে এই দুটি টুল ব্যবহার করুন:
- select_related
এটি ForeignKey এবং OneToOneField-এর জন্য ব্যবহার করুন।
এটি একটি SQL JOIN ব্যবহার করে। এটি একটি মাত্র কুয়েরির মাধ্যমে সম্পর্কিত ডেটা নিয়ে আসে।
- উদাহরণ: Post-এর একটি Author আছে।
- সাধারণ পদ্ধতি (Naive way): ১০০টি পোস্টের জন্য ১০১টি কুয়েরি।
- অপ্টিমাইজড পদ্ধতি: .select_related("author") ব্যবহার করে ১টি কুয়েরি।
- prefetch_related
এটি ManyToManyField এবং reverse ForeignKeys-এর জন্য ব্যবহার করুন।
এটি আলাদা আলাদা কুয়েরি চালায় এবং Python-এ সেগুলোকে যুক্ত (join) করে।
- উদাহরণ: Post-এর অনেকগুলো Tag আছে।
- সাধারণ পদ্ধতি (Naive way): পোস্টের জন্য ১টি কুয়েরি + প্রতিটি পোস্টের ট্যাগের জন্য আলাদা আলাদা কুয়েরি।
- অপ্টিমাইজড পদ্ধতি: .prefetch_related("tags") ব্যবহার করে মোট ২টি কুয়েরি।
প্রো টিপস (Pro Tips):
- লুপে যাওয়ার আগেই সম্পর্কিত ডেটা ফিল্টার করতে Prefetch অবজেক্ট ব্যবহার করুন।
- এগুলো চেইন (chain) করতে পারেন। আপনি একবারে Author এবং Tag পেতে একটি queryset-এ উভয়টিই ব্যবহার করতে পারেন।
- লুপের ভেতরে কোনো prefetched relationship-এর ওপর .filter() কল করা এড়িয়ে চলুন। এটি ক্যাশ (cache) বাইপাস করে এবং পুনরায় ডাটাবেসে হিট করে।
- শুধুমাত্র প্রয়োজনীয় কলামগুলো ফেচ করতে select_related-এর সাথে .only() ব্যবহার করুন।
সারসংক্ষেপ (Summary):
- ForeignKey / OneToOne: select_related ব্যবহার করুন।
- ManyToMany / Reverse FK: prefetch_related ব্যবহার করুন।
এই সমস্যাগুলো দ্রুত শনাক্ত করতে django-debug-toolbar দিয়ে আপনার কুয়েরি সংখ্যা পরীক্ষা করুন।
উৎস (Source): https://dev.to/fhva29/optimizing-django-orm-queries-a-practical-guide-to-selectrelated-and-prefetchrelated-1gpl