ماڈیول اسباق (4/4)
N+1 کا مسئلہ
بیک اینڈ ڈیولپمنٹ میں، اکثر غلطیوں میں سے ایک جو تباہ کن طور پر API کی کارکردگی کو ٹینک کرتی ہے وہ بدنام زمانہ "N + 1 Queries" مسئلہ ہے۔
یہ عام طور پر اس ڈویلپر کے لیے نامعلوم ہو جاتا ہے جو Node.js سے ڈیٹا بیس سے بات کرنے کے لیے "ORMs" (Object-Relational Mappers: جیسے Prisma یا Sequelize) جیسے لائبریری تجریدات کا استعمال کر رہا ہے۔
آفت کی اناٹومی۔
تصور کریں کہ ایک ایپ پوری ای کامرس ہوم پیج کی فہرست کو واپس کرنا چاہتی ہے: تمام پروڈکٹس کے ساتھ زمرہ کے نام کی تار کے ساتھ ہر ایک کا تعلق ہے۔ Node.js کی طرف سے دیکھا گیا، ایک ناتجربہ کار پروگرامر تکراری لوپ لکھے گا:
products = await db.query("SELECT * FROM products");(ایک بڑا، بڑا آپریشن 1)- ڈویلپر 100 کی صف میں ہر ایک
productپر (for..of) اعادہ کرتا ہے - ہر قدم پر، Node.js میں وہ ایک تکراری ذیلی سوال کا انتظار کرتے ہیں
categoryName = await db.query("SELECT name FROM categories WHERE id = " + product.category_id);اور اسے نتیجہ میں شامل کرتے ہیں (N سست، چھوٹے سوالات کے ثانوی تکرار!)
پوسٹگریس ڈیمون کے لیے کل درخواستیں: 1 + 100 مقامی تکرار = 101 مائیکرو نیٹ ورک راؤنڈ ٹرپس Node.js اور DB کے درمیان۔ 101 راؤنڈ ٹرپس خوفناک نیٹ ورک اوور ہیڈ اور بدصورت تاخیر کا سبب بنتے ہیں۔ حقیقی پیمانے پر، N 100 نہیں ہو سکتا بلکہ دریافت کرنے کے لیے کل رسیدوں کی 10,000 قطاریں ہو سکتی ہیں! API 5xx ٹائم آؤٹ کو مارنے سے پہلے واپس نہیں آئے گا۔
اصل مقامی جواب: ایک سوال میں شامل ہوں یا جمع کریں۔
نوڈ میں معمولی ORM کمانڈز کے بجائے ہاتھ سے لکھے ہوئے DBMS تجریدوں کو مہارت کے ساتھ استعمال کرتے ہوئے، ایک ہی ناقابل شکست استفسار میں پھانسیوں کو ملی سیکنڈ میں فیوز کرتا ہے جو "N+1" کی گڑبڑ کو حل کرتا ہے:
SELECT
p.id,
p.name,
c.name AS category_name
FROM products p
JOIN categories c ON p.category_id = c.id;کل API/DB راؤنڈ ٹرپس: 1 منفرد استفسار، جو پوسٹگریس کے اپنے اشاریہ جات کے ذریعہ ریاضی کے لحاظ سے بہتر بنایا گیا ہے، مکمل طور پر 0 ملی سیکنڈ اضافی نیٹ ورک لیٹنسی کے ساتھ ہینڈل کیا گیا ہے۔
JSON جمع متبادل
جدید پوسٹگریس ورژنز یہاں تک کہ آپ کو JSON کے طور پر json_agg کے ساتھ مکمل کمپلیکس جوائن کرنے کی اجازت دیتے ہیں، جس سے آپ کے JavaScript کو products سرنی حاصل کرنے کی اجازت ملتی ہے جس میں ان کے فارمیٹ شدہ جائزوں کی ذیلی صف بھی شامل ہے بغیر کسی مقامی اسکرپٹ گلو کے! (جدید راستوں اور چیلنجوں میں آپ پوسٹگریس کی JSONb شق کا مطالعہ کریں گے۔)
آپ کی باری
آئیے بنانے میں ایک حقیقی N+1 مسئلہ حل کریں۔\nنوڈ نے ایک گلوبل سلیکٹ چلایا ہوگا اور پھر ہر گاہک کو ان کے نام تلاش کرنے کے لیے اعادہ کیا ہوگا اگر وہ آج صبح بھیجے گئے آرڈرز کی بازیافت چاہتا ہے۔\nاسے مجھے ایک ہی مقامی شاٹ میں پرنٹ کرکے 'گاہکوں' کے درمیان جوائن کریں (اصل متنی عرف 'c' کا استعمال کریں 'c' اور 'Ali' )\n)۔ معمولی فیلڈز (رسمی عرف کا سابقہ لگانے پر مجبور کرنا): 'c.first_name' (گاہک کی طرف سے) اور 'o.status' (پینڈنگ آرڈر سے)۔
اشارہ دکھائیں۔
نحو: منتخب کریں c.first_name، o.status from گاہک c JOIN orders o ON c.id = o.customer_id;
3 کوششوں کے بعد حل دستیاب ہے۔
کارکردگی کے لحاظ سے گروپ کو تلاش کرنا
اگر ڈیٹا بیس کے اندر منطقی Group-Bys کو فی قطار اور زمرہ کی کل گنتی حاصل کرنے کے لیے استعمال نہیں کیا جاتا ہے، تو Node.js N+1 میں اڑتے ہوئے DB کو لامتناہی طور پر کال کرے گا۔\nایک واحد استفسار لکھیں جو 'کسٹمرز' سے 'شہر' فیلڈ کو منتخب کرے اور معیاری پوسٹگریس شمار 'COUNT(id)' کو ٹرمینل کی کلید کے ذریعے انوکھا نام استعمال کرتے ہوئے ان کا شمار کرے۔
اشارہ دکھائیں۔
ایک معمولی بات: شہر کا انتخاب کریں، کسٹمرز سے COUNT(id) شہر کے لحاظ سے گروپ کریں؛
3 کوششوں کے بعد حل دستیاب ہے۔