एका Magento डेव्हलपरने ३०० वेगळ्या ProductRepositoryInterface::getById() कॉल्सच्या जागी एक सिंगल कलेक्शन क्वेरी (collection query) वापरली. यामुळे डेटाबेस हिट्स ३०० वरून १ वर आल्या आणि कॅटेगरी पेज लक्षणीय वेगाने लोड झाले. पण याचा परिणाम काय झाला? काही उत्पादने स्टोअरफ्रंटवरून गायब झाली, ज्यामुळे ग्राहक आणि मालक दोघेही गोंधळून गेले.
Magento कॅटेगरी पेजवरील N+1 समस्या
त्या पेजवर ३०० उत्पादने सूचीबद्ध होती. प्रत्येक उत्पादनासाठी कोडने रिपॉझिटरीच्या getById() मेथडद्वारे दोन कस्टम ॲट्रिब्युट्स (custom attributes) मिळवले, ज्यामुळे प्रत्येक उत्पादनासाठी एक क्वेरी तयार होत होती—ही एक क्लासिक N+1 पॅटर्न आहे. प्रत्येक उत्पादनासाठी होणारे हे लोड बदलून एकाच क्वेरीमध्ये सर्व आवश्यक रो (rows) मिळवणारे कलेक्शन वापरल्यामुळे क्वेरीची संख्या लक्षणीयरीत्या कमी झाली. फ्रंट-एंड लॅटन्सी (latency) सुधारली, परंतु उत्पादन यादीतून आता अशी उत्पादने गायब झाली होती जी आधी दिसत होती.
कलेक्शन 'आउट-ऑफ-स्टॉक' (out-of-stock) उत्पादने का लपवते?
Magento चे CatalogInventory मॉड्यूल फ्रंटएंडसाठी तयार केलेल्या कोणत्याही प्रॉडक्ट कलेक्शनमध्ये आपोआप "in-stock" फिल्टर जोडते. जेव्हा स्टोअर सेटिंगमधील Display Out of Stock Products हा पर्याय बंद असतो, तेव्हा हा फिल्टर सक्रिय होतो; उपलब्ध नसलेली उत्पादने दाखवायची नसलेल्या व्यापाऱ्यांसाठी हा एक सामान्य पर्याय आहे.
याउलट, रिपॉझिटरी कधीही स्टॉक फिल्टर लागू करत नाही. ते केवळ उत्पादन अस्तित्वात आहे की नाही हे तपासते आणि इन्व्हेंटरी पातळीची पर्वा न करता ते परत करते. जेव्हा कोड रिपॉझिटरी कॉल्सकडून कलेक्शनकडे वळला, तेव्हा स्टॉक फिल्टरने ज्या उत्पादनांचा साठा (quantity) शून्य होता, ती सर्व उत्पादने शांतपणे काढून टाकली. कोणताही एरर (error) लॉग झाला नाही; कलेक्शनने डेव्हलपरने अपेक्षित केलेल्यापेक्षा कमी रो (rows) परत केले.
व्यापाऱ्यांसाठी याचा अर्थ काय?
स्टोअरफ्रंटवर आउट-ऑफ-स्टॉक SKU आपोआप कमी झाल्यामुळे अनेक समस्या निर्माण होतात:
- फ्रंट-एंड कंपोनंट्सना अपूर्ण माहिती मिळते, ज्यामुळे रिकामे लेबल्स किंवा चुकीचे दर (pricing) दिसू शकतात.
- डीबगिंग (debugging) करणे कठीण होते कारण उत्पादने गायब होणे ही समस्या कोणतीही वॉर्निंग (warning) देत नाही.
बहुतेक ऑटोमेटेड टेस्ट्समध्ये 'इन-स्टॉक' फिक्स्चर्स वापरले जात असल्याने, जोपर्यंत साइट प्रत्यक्ष इन्व्हेंटरीसह चालत नाही, तोपर्यंत हा बग (bug) अनेकदा लपलेला राहतो.
इन्व्हेंटरी लपवल्याशिवाय वेग कसा टिकवून ठेवावा
- डिफॉल्ट स्टॉक फिल्टर वगळा (Skip the default stock filter) – जर तुम्हाला उपलब्धता विचारात न घेता प्रत्येक उत्पादन हवे असेल, तर कलेक्शनमधून तो फिल्टर स्पष्टपणे काढून टाका. Magento प्रत्येक क्वेरीसाठी स्टॉक प्लगइन अक्षम (disable) करण्यासाठी किंवा बदलण्यासाठी पद्धती प्रदान करते.
- अचूकता महत्त्वाची असताना रिपॉझिटरी वापरा – रिपॉझिटरी हे सुनिश्चित करते की प्रत्येक विनंती केलेली प्रॉडक्ट आयडी (product ID) परत केली जाईल, मग ती आउट-ऑफ-स्टॉक असली तरीही. अतिरिक्त क्वेरीज कमी करण्यासाठी निकाल कॅश (cache) करा किंवा तुम्हाला आवश्यक असलेले फक्त आयडी लोड करा.
- रिसोर्स मॉडेल किंवा रॉ SQL (raw SQL) वापरा – आवश्यक ॲट्रिब्युट्ससाठी थेट प्रॉडक्ट टेबल क्वेरी करा. यामुळे सर्व कलेक्शन प्लगइन्स बायपास होतात आणि कोणत्या रो (rows) समाविष्ट करायच्या यावर तुम्हाला पूर्ण नियंत्रण मिळते.
वेग विरुद्ध अचूकता
गोंधळ निर्माण करणाऱ्या N+1 लूपच्या जागी सिंगल कलेक्शन क्वेरी वापरणे नैसर्गिक वाटते; लॅटन्सीमधील घट प्रत्यक्ष जाणवते. तरीही, चुकीच्या उत्पादनांची यादी देणारी वेगवान क्वेरी ही 'ऑप्टिमायझेशन' नसून एक 'दोष' (defect) आहे. डेव्हलपर्सनी केवळ वेगाचा विचार न करता अपूर्ण कॅटलॉग दाखवण्याचा धोका देखील विचारात घेतला पाहिजे.
पुढे काय काळजी घ्यावी
- कॉन्फिगरेशन ड्रिफ्ट (Configuration drift) – Display Out of Stock Products फ्लॅग तुमच्या कस्टम कलेक्शन कोडच्या अपेक्षित वर्तनाशी सुसंगत आहे की नाही याची खात्री करा.
- प्लगइनचे साईड इफेक्ट्स (Plugin side effects) – इतर मॉड्यूल्स कलेक्शनमध्ये स्वतःचे फिल्टर जोडू शकतात. जेव्हा तुम्ही क्वेरी स्ट्रॅटेजी बदलता, तेव्हा प्लगइन स्टॅकची (plugin stack) पुनरावलोकन करा.
धडा स्पष्ट आहे: कलेक्शन वापरून N+1 समस्या सोडवणे तेव्हाच फायदेशीर ठरते जेव्हा तुम्ही कलेक्शनच्या डिफॉल्ट फिल्टर्सची देखील तपासणी करता. Magento च्या इन-बिल्ट स्टॉक फिल्टरकडे दुर्लक्ष केल्यामुळे तुमचे कॅटलॉग शांतपणे कमी होऊ शकते, ज्यामुळे परफॉर्मन्समध्ये झालेली सुधारणा महसूल नुकसानीत बदलू शकते.
