प्रस्तावित दो समाधानों में से कोई भी संभवतः इष्टतम नहीं है, लेकिन समाधान 1 अप्रत्याशित है और इस प्रकार अंतर्निहित रूप से त्रुटिपूर्ण है!
बड़े डेटाबेस के साथ व्यवहार करते समय आप जो पहली चीज़ सीखते हैं, वह यह है कि क्वेरी करने का 'सर्वोत्तम तरीका' अक्सर डेटाबेस में कारकों (मेटा-डेटा के रूप में संदर्भित) पर निर्भर होता है:
- कितनी पंक्तियाँ हैं।
- आप कितनी टेबल क्वेरी कर रहे हैं।
- प्रत्येक पंक्ति का आकार।
इस वजह से, आपकी समस्या के लिए सिल्वर बुलेट समाधान होने की संभावना नहीं है। आपका डेटाबेस मेरे डेटाबेस के समान नहीं है, यदि आपको उपलब्ध सर्वोत्तम प्रदर्शन की आवश्यकता है तो आपको विभिन्न अनुकूलन को बेंचमार्क करना होगा।
आप शायद पाएंगे कि सही इंडेक्स लागू करना और बनानाए> (और MySQL में इंडेक्स के मूल कार्यान्वयन को समझना) आपके डेटाबेस में आपके लिए बहुत कुछ करता है।
प्रश्नों के कुछ सुनहरे नियम हैं जिन्हें शायद ही कभी तोड़ा जाना चाहिए:
- उन्हें लूप स्ट्रक्चर में न करें . जैसा कि अक्सर होता है, एक कनेक्शन बनाने, एक क्वेरी निष्पादित करने और प्रतिक्रिया प्राप्त करने पर ओवरहेड अधिक होता है।
SELECT *
से बचें जब तक आवश्यक न हो . अधिक कॉलम का चयन करने से आपके SQL संचालन के ऊपरी हिस्से में उल्लेखनीय रूप से वृद्धि होगी।- अपनी अनुक्रमणिका जानें .
EXPLAIN
का प्रयोग करें सुविधा ताकि आप देख सकें कि कौन सी अनुक्रमणिका का उपयोग किया जा रहा है, जो उपलब्ध है उसका उपयोग करने के लिए अपने प्रश्नों को अनुकूलित करें और नए बनाएं।
इस वजह से, दोनों में से मैं दूसरी क्वेरी के लिए जाऊंगा (SELECT *
की जगह) केवल आपके इच्छित कॉलम के साथ), लेकिन यदि आपके पास अनुकूलित करने का समय है, तो क्वेरी को संरचित करने के शायद बेहतर तरीके हैं।
हालांकि, गति नहीं होनी चाहिए इसमें आपका एकमात्र विचार हो, सुझाव का उपयोग न करने का एक बड़ा कारण है:
PREDICTABILITY:रीड-लॉक एक अच्छी बात क्यों है
अन्य उत्तरों में से एक से पता चलता है कि टेबल को लंबे समय तक लॉक करना एक बुरी बात है, और इसलिए बहु-क्वेरी समाधान अच्छा है।
मैं तर्क दूंगा कि यह सच्चाई से आगे नहीं हो सकता . वास्तव में, मैं तर्क दूंगा कि कई मामलों में एकल लॉकिंग चलाने की भविष्यवाणी SELECT
क्वेरी उस क्वेरी को चलाने के लिए अनुकूलन और गति लाभों की तुलना में एक बड़ा तर्क है।
सबसे पहले, जब हम SELECT
चलाते हैं MyISAM या InnoDB डेटाबेस (MySQL के लिए डिफ़ॉल्ट सिस्टम) पर (केवल-पढ़ने के लिए) क्वेरी, क्या होता है कि तालिका रीड-लॉक हो जाती है। यह किसी भी WRITE ऑपरेशन को टेबल पर तब तक होने से रोकता है जब तक कि रीड-लॉक सरेंडर नहीं कर दिया जाता (या तो हमारा SELECT
क्वेरी पूर्ण या विफल)। अन्य SELECT
क्वेरी प्रभावित नहीं होती हैं, इसलिए यदि आप एक बहु-थ्रेडेड एप्लिकेशन चला रहे हैं, तो वे काम करना जारी रखेंगे।
यह देरी अच्छी बात है। क्यों, आप पूछ सकते हैं? संबंधपरक डेटा अखंडता।
आइए एक उदाहरण लेते हैं:हम एक गेम पर उपयोगकर्ताओं के समूह की सूची में वर्तमान में आइटम की सूची प्राप्त करने के लिए एक ऑपरेशन चला रहे हैं, इसलिए हम इसमें शामिल होते हैं:
SELECT * FROM `users` JOIN `items` ON `users`.`id`=`items`.`inventory_id` WHERE `users`.`logged_in` = 1;
क्या होगा यदि, इस क्वेरी ऑपरेशन के दौरान, कोई उपयोगकर्ता किसी आइटम को किसी अन्य उपयोगकर्ता को ट्रेड करता है? इस क्वेरी का उपयोग करते हुए, हम खेल की स्थिति देखते हैं जैसा कि हमने क्वेरी शुरू करते समय किया था:आइटम एक बार मौजूद होता है, उस उपयोगकर्ता की सूची में जिसके पास यह क्वेरी चलाने से पहले था।
लेकिन, अगर हम इसे लूप में चला रहे हैं तो क्या होगा?
इस पर निर्भर करते हुए कि उपयोगकर्ता ने उसका विवरण पढ़ने से पहले या बाद में उसका व्यापार किया, और किस क्रम में हम दो खिलाड़ियों की सूची पढ़ते हैं, इसकी चार संभावनाएं हैं:
- आइटम को पहले उपयोगकर्ता की सूची में दिखाया जा सकता है (स्कैन उपयोगकर्ता बी -> स्कैन उपयोगकर्ता ए -> आइटम का कारोबार या स्कैन उपयोगकर्ता बी -> स्कैन उपयोगकर्ता ए -> आइटम का कारोबार)।
- आइटम दूसरे उपयोगकर्ता की सूची में दिखाया जा सकता है (आइटम ट्रेड किया गया -> स्कैन उपयोगकर्ता ए -> स्कैन उपयोगकर्ता बी या आइटम व्यापार -> स्कैन उपयोगकर्ता बी -> स्कैन उपयोगकर्ता ए)।
- आइटम दोनों में दिखाया जा सकता है इन्वेंट्री (स्कैन यूजर ए -> आइटम ट्रेडेड -> स्कैन यूजर बी)।
- आइटम न तो . में दिखाया जा सकता है उपयोगकर्ता की सूची (स्कैन उपयोगकर्ता बी -> आइटम कारोबार -> स्कैन उपयोगकर्ता ए)।
इसका मतलब यह है कि हम क्वेरी के परिणामों की भविष्यवाणी करने या संबंधपरक अखंडता सुनिश्चित करने में असमर्थ होंगे .
यदि आप मंगलवार की आधी रात को आइटम आईडी 1000000 वाले व्यक्ति को $5,000 देने की योजना बना रहे हैं, तो मुझे आशा है कि आपके पास $10k है। यदि आपका प्रोग्राम स्नैपशॉट लेते समय अद्वितीय आइटम के अद्वितीय होने पर निर्भर करता है, तो आप संभवतः इस प्रकार की क्वेरी के साथ एक अपवाद उठाएंगे।
लॉक करना अच्छा है क्योंकि इससे अनुमानितता बढ़ जाती है और अखंडता . की रक्षा करता है परिणामों की।
नोट:आप एक लूप को एक लेनदेन के साथ लॉक करने के लिए बाध्य कर सकते हैं , लेकिन यह अभी भी . होगा धीमे रहो।
ओह, और अंत में, तैयार कथनों का उपयोग करें!
आपको कभी नहीं . करना चाहिए एक बयान है जो इस तरह दिखता है:
mysqli_query("SELECT * FROM Table2 WHERE ColumnAId=" . $row['ColumnAId'], $con);
mysqli
तैयार किए गए बयानों के लिए समर्थन
है . उनके बारे में पढ़ें और उनका उपयोग करें, वे आपके डेटाबेस में कुछ भयानक घटना
से बचने में आपकी सहायता करेंगे। ।