कौन सा तेज / सबसे अच्छा है? SELECT * या SELECT column1, colum2, column3, etc


166

मैंने सुना है कि SELECT *आमतौर पर एसक्यूएल कमांड लिखते समय उपयोग करने के लिए बुरा अभ्यास होता है क्योंकि यह SELECTआपके लिए विशेष रूप से आवश्यक कॉलमों के लिए अधिक कुशल है ।

यदि मुझे SELECTकिसी तालिका में प्रत्येक कॉलम की आवश्यकता है , तो क्या मुझे उपयोग करना चाहिए

SELECT * FROM TABLE

या

SELECT column1, colum2, column3, etc. FROM TABLE

क्या इस मामले में दक्षता वास्तव में मायने रखती है? मुझे लगता है कि SELECT *आंतरिक रूप से अधिक इष्टतम होगा यदि आपको वास्तव में सभी डेटा की आवश्यकता है, लेकिन मैं यह डेटाबेस की वास्तविक समझ के साथ नहीं कह रहा हूं।

मैं यह जानने के लिए उत्सुक हूं कि इस मामले में सबसे अच्छा अभ्यास क्या है।

अद्यतन: मैं शायद निर्दिष्ट करना चाहिए कि केवल उसी परिस्थिति मैं वास्तव में चाहते हैं चाहते हैं एक ऐसा करने के लिए SELECT *है जब मैं एक मेज से डेटा का चयन कर रहा हूँ मैं कहाँ पता सभी स्तंभों हमेशा पुनः प्राप्त किया जा करने की आवश्यकता होगी, तब भी जब नए कॉलम जोड़ रहे हैं।

हालाँकि मैंने जो प्रतिक्रियाएँ दी हैं, यह अभी भी एक बुरे विचार की तरह लगता है और SELECT *कभी भी बहुत अधिक तकनीकी कारणों के लिए इस्तेमाल नहीं किया जाना चाहिए, जिनके बारे में मुझे कभी भी जानकारी नहीं है।




1
हाँ, यह उन लोगों में से अधिकांश का एक डुप्लिकेट है।
जॉर्ज स्टॉकर

जवाबों:


168

विशिष्ट स्तंभों का चयन करने का एक कारण यह है कि यह इस संभावना को बढ़ाता है कि SQL सर्वर तालिका डेटा को क्वेरी करने के बजाय अनुक्रमित से डेटा तक पहुंच सकता है।

यहाँ एक पोस्ट है जिसके बारे में मैंने लिखा है: वास्तविक कारण चुनिंदा प्रश्न खराब इंडेक्स कवरेज हैं

यह परिवर्तन करने के लिए भी कम नाजुक है, क्योंकि डेटा का उपभोग करने वाले किसी भी कोड को भविष्य में टेबल स्कीमा में किए गए परिवर्तनों की परवाह किए बिना समान डेटा संरचना प्राप्त होगी।


3
इसके लिए +1। यदि संदर्भित किए गए सभी कॉलम एकल इंडेक्स ("कवरिंग इंडेक्स") में मौजूद हैं, तो आपने सोना मारा है।
इयान नेल्सन

22
यह उनके सवाल का जवाब नहीं है - "अगर मुझे एक तालिका में प्रत्येक कॉलम का चयन करने की आवश्यकता है, ..." - उस मामले में, * बनाम कॉल 1, .., कॉलन कोई फर्क नहीं पड़ता (लेकिन यह प्रोग्रामर समय के लिए नहीं है) चूँकि * छोटा है!)।
मैट रोजिश

3
यह अभी भी मायने रखता है, क्योंकि चयन सूची अनुबंध का एक रूप है, जो कि SQL एक संग्रहीत प्रक्रिया में है।
एरिक जेड बियर्ड

4
जबकि जॉन जो कहते हैं वह पूरी तरह से सही है, और एक बहुत ही मान्य बिंदु है, मुझे इस बात पर ध्यान देना होगा कि ASKED के बारे में सवाल यह है कि क्या वे पहले से ही सभी स्तंभों के लिए पूछ रहे हैं। प्रश्न के इस भाग के कारण, स्कीमा परिवर्तन के सामने वास्तविक मुद्दे नाजुकता हैं।
आईडीसोपोर्टर

1
@MattRogish सर आपको सही तरीके से मिला, क्या इन दोनों विधियों (* vsall_column_names) के बीच कोई प्रदर्शन अंतर है जबकि हमारे पास हजारों पंक्तियाँ हैं और हम सूचकांक के साथ SELECT (WHERE क्लॉज में) करते हैं ??
संतोश

59

आपके विनिर्देशन को देखते हुए कि आप सभी कॉलमों का चयन कर रहे हैं, इस समय थोड़ा अंतर है । हालांकि, एहसास है कि डेटाबेस स्कीमा परिवर्तन करते हैं। यदि आप उपयोग SELECT *करते हैं तो आप किसी भी नए कॉलम को तालिका में शामिल करने जा रहे हैं, भले ही सभी संभावना में, आपका कोड उस नए डेटा का उपयोग करने या प्रस्तुत करने के लिए तैयार नहीं है। इसका मतलब है कि आप अपने सिस्टम को अप्रत्याशित प्रदर्शन और कार्यक्षमता में बदलाव के लिए उजागर कर रहे हैं।

आप इसे मामूली लागत के रूप में खारिज करने के लिए तैयार हो सकते हैं, लेकिन यह महसूस करें कि उन स्तंभों की आवश्यकता है जो आपको अभी भी होने चाहिए:

  1. डेटाबेस से पढ़ें
  2. नेटवर्क में भेजा गया
  3. आपकी प्रक्रिया में शामिल किया गया
  4. (ADO- प्रकार प्रौद्योगिकियों के लिए) डेटा-टेबल इन-मेमोरी में सहेजा गया
  5. अनदेखा और त्याग / कचरा-एकत्र

आइटम # 1 में कई संभावित कवर इंडेक्स को समाप्त करने सहित कई छिपी हुई लागतें हैं, जिससे डेटा-पेज लोड (और सर्वर कैश थ्रेशिंग) होता है, जिससे पंक्ति / पृष्ठ / टेबल लॉक को अन्यथा से बचा जा सकता है।

बनाम *और एक ही संभावित बचत कॉलम को निर्दिष्ट करने की संभावित बचत के खिलाफ इसे संतुलित करें :

  1. प्रोग्रामर को कॉलम जोड़ने के लिए SQL को फिर से चालू करने की आवश्यकता नहीं है
  2. SQL का नेटवर्क-ट्रांसपोर्ट छोटा / तेज होता है
  3. SQL सर्वर क्वेरी पार्स / सत्यापन समय
  4. SQL सर्वर क्वेरी योजना कैश

आइटम 1 के लिए, वास्तविकता यह है कि आप किसी भी नए कॉलम का उपयोग करने के लिए कोड जोड़ने / बदलने के लिए जा रहे हैं, इसलिए यह धो सकता है।

आइटम 2 के लिए, अंतर शायद ही आपको किसी पैकेट-आकार या नेटवर्क पैकेट की संख्या में धकेलने के लिए पर्याप्त है। यदि आप उस बिंदु पर पहुँचते हैं जहाँ SQL कथन संचरण समय प्रमुख मुद्दा है, तो आपको संभवतः पहले कथनों की दर को कम करना होगा।

आइटम 3 के लिए, *वैसे भी होने वाले विस्तार के रूप में कोई बचत नहीं है, जिसका अर्थ है कि तालिका (एस) स्कीमा को किसी भी तरह से परामर्श करना है। वास्तविक रूप से, स्तंभों को सूचीबद्ध करने में समान लागत आएगी क्योंकि उन्हें स्कीमा के खिलाफ मान्य होना होगा। दूसरे शब्दों में यह एक पूर्ण धो है।

आइटम 4 के लिए, जब आप विशिष्ट कॉलम निर्दिष्ट करते हैं, तो आपकी क्वेरी प्लान कैश बड़ी हो सकती है, लेकिन केवल तभी जब आप कॉलम के विभिन्न सेटों के साथ काम कर रहे हों (जो कि आपके द्वारा निर्दिष्ट नहीं है)। इस मामले में, आप चाहते हैं अलग कैश प्रविष्टियों क्योंकि आप विभिन्न योजनाओं के रूप में की जरूरत है चाहता हूँ।

तो, यह सब नीचे आता है, क्योंकि जिस तरह से आपने प्रश्न को निर्दिष्ट किया था, आखिरकार स्कीमा संशोधनों के सामने समस्या को हल करने के लिए। यदि आप इस स्कीमा को ROM में जला रहे हैं (ऐसा होता है), तो एक *पूरी तरह से स्वीकार्य है।

हालांकि, मेरी सामान्य दिशानिर्देश यह है कि आपको केवल उन कॉलमों का चयन करना चाहिए जिनकी आपको आवश्यकता है, जिसका अर्थ है कि कभी-कभी ऐसा लगेगा जैसे आप उन सभी से पूछ रहे हैं, लेकिन डीबीए और स्कीमा विकास का मतलब है कि कुछ नए कॉलम दिखाई दे सकते हैं जो क्वेरी को बहुत प्रभावित कर सकते हैं। ।

मेरी सलाह है कि आपको हमेशा विशिष्ट स्तंभों का चयन करना चाहिए । याद रखें कि आप जो भी करते हैं उसमें अच्छा मिलता है, इसलिए इसे सही तरीके से करने की आदत डालें।

यदि आप सोच रहे हैं कि कोड बदलने के बिना एक स्कीमा क्यों बदल सकता है, तो ऑडिट लॉगिंग, प्रभावी / समाप्ति तिथियों और अन्य समान चीजों के बारे में सोचें जो अनुपालन मुद्दों के लिए व्यवस्थित रूप से डीबीए द्वारा जोड़े जाते हैं। अंडरहैंड किए गए परिवर्तनों का एक अन्य स्रोत सिस्टम या उपयोगकर्ता-परिभाषित क्षेत्रों में कहीं और प्रदर्शन के लिए विकृति है।


3
"वास्तविकता यह है कि आप किसी भी नए कॉलम को वैसे भी जोड़ने के लिए कोड जोड़ने / बदलने जा रहे हैं, इसलिए यह धोना है।" -यदि आप अपने कोड में नाम से प्रत्येक कॉलम को मैन्युअल रूप से पढ़ रहे हैं। यदि आप स्वचालित मानचित्रण का उपयोग कर रहे हैं, तो यह मामला नहीं है, और यह मुद्दा महत्वपूर्ण हो जाता है।
जोश नं।

36

आपको केवल उन कॉलम का चयन करना चाहिए जिनकी आपको आवश्यकता है। यहां तक ​​कि अगर आपको सभी कॉलमों की आवश्यकता है, तो कॉलम नामों को सूचीबद्ध करना अभी भी बेहतर है ताकि एसक्यूएल सर्वर को कॉलम के लिए सिस्टम टेबल को क्वेरी न करना पड़े।

यदि कोई व्यक्ति तालिका में कॉलम जोड़ता है, तो भी आपका आवेदन टूट सकता है। आपके कार्यक्रम को ऐसे कॉलम मिलेंगे जिनकी उसे उम्मीद भी नहीं थी और यह नहीं जान सकता कि उन्हें कैसे संसाधित किया जाए।

इसके अलावा यदि तालिका में एक बाइनरी कॉलम है तो क्वेरी बहुत अधिक धीमी होगी और अधिक नेटवर्क संसाधनों का उपयोग करेगी।


6
अहा तो * का उपयोग करके आप डीबी के लिए अतिरिक्त काम जोड़ रहे हैं। ठीक है कि एक कारण है जिसके बारे में मैंने नहीं सोचा था।
अंकुर

1
जल्दी गलतियों को तोड़ने / पकड़ने के जोखिम के लिए +1। मुझे लगता है कि दक्षता की चर्चा वैध है लेकिन YAGNI।
नाखून

6
SQL सर्वर को मान्य या जाँचने की आवश्यकता नहीं होगी कि क्या "col1" वैसे भी निर्दिष्ट तालिका में है, अर्थात क्वेरी सिस्टम तालिका?
पैट्रिक

3
सबसे बड़ा प्रदर्शन हिट शायद अनुक्रमण से संबंधित है। यदि आप जिस कॉलम की तलाश कर रहे हैं, वह उस डेटा को खोजने के लिए उपयोग किए गए इंडेक्स का एक हिस्सा है, जो सर्वर डेटा को वहीं लाएगा, यदि आप एक सिलेक्ट * करते हैं, तो यह सबसे अधिक संभावना है कि उसे एक बुकमार्क लुकअप कहा जाता है, जिसके लिए एक अतिरिक्त की आवश्यकता होती है बाकी अंतर्निहित डेटा को खोजने के लिए स्कैन करें, जिसकी आपको आवश्यकता भी नहीं है।
कोबसुवे

3
@ पैट्रिक - ऑन स्पॉट। * से बचने के लिए अच्छे कारणों के बहुत सारे लेकिन उनमें से एक नहीं है।
मार्टिन स्मिथ

31

चार बड़े कारण हैं जो select *एक बुरी बात है:

  1. सबसे महत्वपूर्ण व्यावहारिक कारण यह है कि यह उपयोगकर्ता को जादुई रूप से उस आदेश को जानने के लिए मजबूर करता है जिसमें कॉलम वापस आ जाएगा। स्पष्ट होना बेहतर है, जो आपको टेबल बदलने से भी बचाता है, जो अच्छी तरह से बहस करता है ...

  2. यदि आप जिन स्तंभ नाम का उपयोग परिवर्तन कर रहे हैं, तो जब आप स्तंभ का उपयोग करने का प्रयास कर रहे हैं, तो इसके बजाय इसे जल्दी पकड़ना बेहतर होगा (SQL कॉल के बिंदु पर) अब मौजूद नहीं है (या इसका नाम बदल गया है, आदि) )

  3. कॉलम नामों को सूचीबद्ध करने से आपका कोड कहीं अधिक स्व-प्रलेखित हो जाता है, और इसलिए संभवतः अधिक पठनीय होता है।

  4. यदि आप एक नेटवर्क (या यहां तक ​​कि अगर आप नहीं हैं) पर स्थानांतरित कर रहे हैं, तो आपको जिन कॉलमों की आवश्यकता नहीं है वे बस बेकार हैं।


7
"सबसे महत्वपूर्ण व्यावहारिक कारण यह है कि यह उपयोगकर्ता को जादुई रूप से उस आदेश को जानने के लिए मजबूर करता है जिसमें कॉलम वापस किया जाएगा।" मैं यह नहीं देखता कि यह कैसा मुद्दा है। किसी भी आधुनिक DB क्लाइंट में, आप नाम से कॉलम पढ़ते हैं, ऑर्डर नहीं।
जोश नं।

मैं अपनी SQL को C इंटरफ़ेस के माध्यम से चलाता हूं, इसलिए मुझे वास्तव में नहीं पता होगा कि "DB क्लाइंट" में कला की स्थिति क्या है। लेकिन मुझे लगता है कि शायद आप जिस तरह के ग्राहक के बारे में बात कर रहे हैं, वह कुछ गैर-मानक गैर-SQL जादू कर रहा है। (उदाहरण के लिए, SQLite में, sqlite3_master को उद्धृत करते हुए यह पता लगाने के लिए कि आपके *नाम के सेट को कैसे बदलना है ।)
pkh

और इस से आगे यह है कि कितने लोग आधुनिक अनुप्रयोगों में कोड लिखते हैं जो या तो स्तंभ नामों के सूचकांक का उपयोग करते हैं? अधिकांश लोग निश्चित रूप से डेटा के लिए कुछ प्रकार के मैपर और कैशिंग के एक पूरे ढेर का उपयोग कर रहे हैं जो बासी होने की अनुमति है। व्यक्तिगत रूप से, पहले कोड लिखें, और फिर चिंता करें कि क्या आपके पास बाद में प्रदर्शन के मुद्दे हैं।
कॉलिन विजमैन

10

कॉलम सूची निर्दिष्ट करना आमतौर पर सबसे अच्छा विकल्प होता है क्योंकि यदि कोई व्यक्ति तालिका में किसी स्तंभ को जोड़ता / सम्मिलित करता है तो आपका आवेदन प्रभावित नहीं होगा।


7

कॉलम नाम निर्दिष्ट करना निश्चित रूप से तेज़ है - सर्वर के लिए। लेकिन अगर

  1. प्रदर्शन कोई बड़ा मुद्दा नहीं है (उदाहरण के लिए, यह सैकड़ों के साथ एक वेबसाइट सामग्री डेटाबेस है, शायद हजारों - लेकिन प्रत्येक तालिका में लाखों - पंक्तियों की नहीं); तथा
  2. आपका काम एक जटिल ढांचे को बंद करने के बजाय एक सामान्य ढांचे का उपयोग करके कई छोटे, समान अनुप्रयोगों (जैसे सार्वजनिक-सामना करने वाली सामग्री-प्रबंधित वेबसाइट) बनाना है; तथा
  3. लचीलापन महत्वपूर्ण है (प्रत्येक साइट के लिए डीबी स्कीमा के अनुकूलन के बहुत सारे);

फिर आप सेलेक्ट * के साथ चिपके रहना बेहतर है। हमारे ढांचे में, SELECT * के भारी उपयोग से हमें एक नई वेबसाइट प्रबंधित सामग्री फ़ील्ड को तालिका में शामिल करने की अनुमति मिलती है, जिससे यह CMS के सभी लाभ (संस्करण, वर्कफ़्लो / अनुमोदन आदि) देते हैं, जबकि केवल एक कोड को स्पर्श करते समय। दो दर्जन बिंदुओं के बजाय दो बिंदु।

मुझे पता है कि डीबी गुरु इसके लिए मुझसे नफरत करने जा रहे हैं - आगे बढ़ो, मुझे वोट दो - लेकिन मेरी दुनिया में, डेवलपर समय कम है और सीपीयू साइकिल प्रचुर मात्रा में हैं, इसलिए मैं तदनुसार समायोजित करता हूं कि मैं क्या संरक्षण करता हूं और जो मैं बर्बाद करता हूं।


1
यह भी उपयोग करने के लिए ORMs को बहुत सरल बनाता है। जब क्वेरी क्वेरी बिल्डिंग ऑब्जेक्ट को चारों ओर से गुजरते हुए बनाई जाती है, तो जरूरी नहीं कि कौन सा कॉलम कोड के अन्य भागों (अनुमति की जांच, आपके पास क्या है) द्वारा आवश्यक था। इसलिए कॉलम को सीमित करने के लिए, किसी को हर बार एक प्रश्न लिखने की आवश्यकता की जांच करनी होगी। यह व्यर्थ है, IMO। जब प्रश्न धीमा हो जाता है (लॉग!), तो कोई उनमें सुधार कर सकता है।
उपनगर

6

सेलेक्ट * एक नेटवर्क पर क्वेरी न भेजे जाने पर भी एक बुरा अभ्यास है।

  1. आपकी ज़रूरत से अधिक डेटा का चयन करना क्वेरी को कम कुशल बनाता है - सर्वर को अतिरिक्त डेटा को पढ़ना और स्थानांतरित करना पड़ता है, इसलिए इसमें समय लगता है और सिस्टम पर अनावश्यक भार पैदा करता है (न केवल नेटवर्क, जैसा कि दूसरों ने उल्लेख किया है, लेकिन डिस्क, सीपीयू आदि भी। )। इसके अतिरिक्त, सर्वर क्वेरी को ऑप्टिमाइज़ करने में असमर्थ है और साथ ही यह (उदाहरण के लिए, क्वेरी के लिए कवरिंग इंडेक्स का उपयोग) कर सकता है।
  2. कुछ समय बाद आपकी तालिका संरचना बदल सकती है, इसलिए SELECT * कॉलम का एक अलग सेट लौटाएगा। तो, आपके एप्लिकेशन को अप्रत्याशित संरचना का डेटासेट मिल सकता है और नीचे की ओर कहीं टूट सकता है। स्पष्ट रूप से स्तंभों को बताते हुए कि आप या तो ज्ञात संरचना का डेटासेट प्राप्त करते हैं, या डेटाबेस स्तर पर एक स्पष्ट त्रुटि प्राप्त करते हैं (जैसे 'स्तंभ नहीं मिला')।

बेशक, यह सब एक छोटी और सरल प्रणाली के लिए ज्यादा मायने नहीं रखता है।


4

प्रदर्शन बुद्धिमान, विशिष्ट स्तंभों के साथ चयन तेज हो सकता है (सभी डेटा में पढ़ने की आवश्यकता नहीं है)। यदि आपकी क्वेरी वास्तव में सभी स्तंभों का उपयोग करती है, तो स्पष्ट मापदंडों के साथ चयन अभी भी पसंद किया जाता है। किसी भी गति अंतर मूल रूप से ध्यान देने योग्य और निरंतर-समय के पास होगा। एक दिन आपका स्कीमा बदल जाएगा, और इसके कारण होने वाली समस्याओं को रोकने के लिए यह अच्छा बीमा है।


आप ध्यान नहीं देने वाले के बारे में गलत हैं क्योंकि मैंने कई DB के साथ किए गए चेक से यह स्पष्ट था कि प्रत्येक कॉलम का चयन करना, भले ही उन सभी को, बहुत तेज है। कुछ मामलों में यह तीन गुना तेज था।
शाहर एल्लाद

4

यहाँ अब तक बहुत सारे अच्छे कारणों का जवाब दिया गया है, यहाँ एक और उल्लेख किया गया है।

स्पष्ट रूप से स्तंभों का नामकरण आपको नीचे सड़क के रखरखाव में मदद करेगा। कुछ बिंदु पर आप परिवर्तन या समस्या निवारण करने जा रहे हैं, और अपने आप से पूछें कि "कहां है वह स्तंभ जिसका उपयोग किया गया है"।

यदि आपको नाम स्पष्ट रूप से सूचीबद्ध हैं, तो उस कॉलम के हर संदर्भ को खोजना - आपकी सभी संग्रहीत प्रक्रियाओं, विचारों आदि के माध्यम से - सरल है। बस अपने DB स्कीमा के लिए एक क्रिएट स्क्रिप्ट को डंप करें, और इसके माध्यम से टेक्स्ट सर्च करें।


3

निश्चित रूप से कॉलम को परिभाषित करना, क्योंकि SQL सर्वर को उन्हें खींचने के लिए कॉलम पर एक लुकअप नहीं करना होगा। यदि आप कॉलम परिभाषित करते हैं, तो SQL उस चरण को छोड़ सकता है।


यह है: 1) अप्रासंगिक, क्योंकि SQL सर्वर को तालिका स्कीमा को किसी भी तरह से संदर्भित करना होता है (स्तंभ नामों को मान्य करने के लिए या ज्ञात-मान्य स्तंभ नामों को देखने के लिए) 2) उस प्रश्न से प्रासंगिक नहीं है, जहां सभी कॉलम संदर्भित किए जा रहे हैं। ASKED के रूप में एकमात्र मुद्दा नाजुकता w / स्कीमा परिवर्तन है।
२०:०० पर आईडीसोपोर्टर

डाउनवोट किया गया, क्योंकि यह स्तंभों की परवाह किए बिना मान्य होगा।
जॉन गिब

3

आपके लिए आवश्यक कॉलम निर्दिष्ट करना हमेशा बेहतर होता है, यदि आप इसके बारे में एक बार सोचते हैं, तो SQL को यह सोचने की ज़रूरत नहीं है कि हर बार जब आप क्वेरी करते हैं तो "wtf है *"। उसके शीर्ष पर, कोई बाद में उस तालिका में कॉलम जोड़ सकता है जिसकी आपको वास्तव में आपकी क्वेरी में आवश्यकता नहीं है और आप अपने सभी कॉलमों को निर्दिष्ट करके उस स्थिति में बेहतर होंगे।


1
यह सच नहीं है: SQL सर्वर को अभी भी प्रत्येक कॉलम को पार्स करना चाहिए और देखना चाहिए कि क्या यह कैटलॉग में मौजूद है, जबकि यह जानता है कि "*" करता है (और हाँ, * सभी कॉलों तक विस्तारित है)। किसी भी तरह से, यह डीबीएमएस के लिए एक (जब तक आपके पास 24,000 कॉलम नहीं है) के लिए तुच्छ रूप से आसान है, इसलिए मैं शर्त लगाता हूं कि यह भी उसी तरह है
मैट रोजिश

मुझे लगता है कि बेहतर बिंदु यह है कि कई गायब हैं और दुर्भाग्य से, यह उत्तर केवल दूसरे को संबोधित करता है, यह है कि यदि स्कीमा / तालिका परिवर्तन होता है (यानी नए कॉलम जोड़े गए) तो यह चीजों को नहीं तोड़ देगा।
सीन हैली

1
यह एक पूर्ण धुलाई है जैसे * विस्तार के लिए कॉलम देखना, प्रदान किए गए कॉलम नामों को मान्य करने के समान है।
२०:०२ पर आईडीसोपोर्टर

3

"सेलेक्ट *" के साथ समस्या वह डेटा लाने की संभावना है जिसकी आपको वास्तव में आवश्यकता नहीं है। वास्तविक डेटाबेस क्वेरी के दौरान, चयनित कॉलम वास्तव में गणना में शामिल नहीं होते हैं। क्या वास्तव में "भारी" आपके ग्राहक के लिए डेटा ट्रांसपोर्ट है, और किसी भी कॉलम को जिसकी आपको वास्तव में आवश्यकता नहीं है, बस नेटवर्क बैंडविड्थ को बर्बाद कर रहा है और उस समय को जोड़ रहा है जब आप लौटने के लिए क्वेरी का इंतजार कर रहे हैं।

यहां तक ​​कि अगर आप एक "चयन * ..." से लाए गए सभी कॉलम का उपयोग करते हैं, तो अभी के लिए है। यदि भविष्य में आप तालिका / दृश्य लेआउट बदलते हैं और अधिक कॉलम जोड़ते हैं, तो आप उन्हें अपने चयन में लाना शुरू कर देंगे, भले ही आपको उनकी आवश्यकता न हो।

एक और बिंदु जिसमें "चयन *" कथन बुरा है, दृश्य निर्माण पर है। यदि आप "सेलेक्ट *" का उपयोग करके एक दृश्य बनाते हैं और बाद में अपनी तालिका में कॉलम जोड़ते हैं, तो परिभाषा और डेटा लौटाए गए मेल नहीं खाएंगे, और आपको उन्हें फिर से काम करने के लिए अपने विचारों को फिर से जोड़ना होगा।

मुझे पता है कि "चयन *" लिखना आकर्षक है, क्योंकि मैं वास्तव में अपने प्रश्नों पर सभी क्षेत्रों को मैन्युअल रूप से निर्दिष्ट करना पसंद नहीं करता, लेकिन जब आपका सिस्टम विकसित होना शुरू होता है, तो आप देखेंगे कि यह अतिरिक्त समय बिताने के लायक है / क्षेत्रों को निर्दिष्ट करने के बजाय अधिक समय बिताने और अपने विचारों पर बग हटाने या अपने ऐप का अनुकूलन करने का प्रयास।


VIEWs पर बिंदु बहुत महत्वपूर्ण है। यदि आप तालिका में कॉलम जोड़ते हैं, तो न केवल आपको सभी कॉलम नहीं मिलेंगे (इसके बावजूद कि * आप क्या सोचते होंगे), लेकिन वे तालिका के वास्तविक लेआउट से मेल भी नहीं खा सकते हैं।
यूरो माइकेली

3

जबकि स्पष्ट रूप से सूची स्तंभ प्रदर्शन के लिए अच्छा है, पागल मत हो।

इसलिए यदि आप सभी डेटा का उपयोग करते हैं, तो सादगी के लिए SELECT * का प्रयास करें (कल्पना करें कि कई कॉलम हैं और एक JOIN ... क्वेरी भयानक हो सकती है)। फिर - उपाय। स्पष्ट रूप से सूचीबद्ध कॉलम नामों के साथ क्वेरी से तुलना करें।

प्रदर्शन के बारे में अटकलें न लगाएं, इसे मापें!

स्पष्ट लिस्टिंग में सबसे अधिक मदद मिलती है जब आपके पास कुछ कॉलम होते हैं जिसमें बड़ा डेटा (जैसे पोस्ट या लेख का निकाय), और दिए गए क्वेरी में इसकी आवश्यकता नहीं होती है। फिर इसे अपने उत्तर में वापस न करके DB सर्वर समय, बैंडविड्थ और डिस्क थ्रूपुट को बचा सकता है। आपका क्वेरी परिणाम भी छोटा होगा, जो किसी भी क्वेरी कैश के लिए अच्छा है।


3

आपको वास्तव में केवल उन फ़ील्ड्स का चयन करना चाहिए जिनकी आपको आवश्यकता है, और केवल आवश्यक संख्या, अर्थात

SELECT Field1, Field2 FROM SomeTable WHERE --(constraints)

डेटाबेस के बाहर, डायनेमिक क्वेरीज़ इंजेक्शन हमलों और विकृत डेटा के जोखिम को चलाते हैं। आमतौर पर आप संग्रहीत प्रक्रियाओं या पैरामीटर किए गए प्रश्नों का उपयोग करके इसे गोल करते हैं। इसके अलावा (हालांकि वास्तव में इतनी समस्या नहीं है) हर बार एक गतिशील क्वेरी निष्पादित होने पर सर्वर को एक निष्पादन योजना उत्पन्न करनी होती है।


"सर्वर को हर बार एक गतिशील क्वेरी निष्पादित होने पर एक निष्पादन योजना उत्पन्न करनी होती है" जो मुझे लगता है कि क्वेरी को धीमा कर देती है। धन्यवाद।
अंकुर

गतिशील sql का उपयोग करने के प्रदर्शन के मुद्दों को शायद केवल बहुत ही उच्च भार परिदृश्यों में महसूस किया जाएगा, Sql Server कुशलतापूर्वक क्वेरी योजनाओं के प्रबंधन में बहुत अच्छा है।
मैथ्यू एबट ने

2

यदि आप * या कॉलम का उपयोग करते हैं तो चयन भी उतना ही कुशल है (वेग के संदर्भ में)।

अंतर स्मृति का है, वेग का नहीं। जब आप कई स्तंभों का चयन करते हैं, तो SQL सर्वर को आपके द्वारा अनुरोध किए गए सभी स्तंभों के लिए सभी डेटा सहित, आपको सेवा करने के लिए मेमोरी स्पेस आवंटित करना चाहिए, भले ही आप उनमें से केवल एक का उपयोग कर रहे हों।

प्रदर्शन के मामले में क्या मायने रखता है यह अतिश्योक्ति योजना है जो बदले में आपके WHERE क्लॉज और JOIN, OUTER JOIN, आदि की संख्या पर बहुत अधिक निर्भर करती है ...

अपने प्रश्न के लिए बस SELECT * का प्रयोग करें। यदि आपको सभी कॉलमों की आवश्यकता है तो कोई प्रदर्शन अंतर नहीं है।


2

स्पष्ट फ़ील्ड नाम बनाम *, यदि और केवल तभी उपयोग करना अधिक तेज़ नहीं है, तो आपको सभी फ़ील्ड के लिए डेटा प्राप्त करना होगा।

आपके क्लाइंट सॉफ़्टवेयर को दिए गए फ़ील्ड के क्रम पर निर्भर नहीं होना चाहिए, इसलिए यह एक बकवास भी है।

और यह संभव है (हालांकि संभावना नहीं है) कि आपको * का उपयोग करके सभी फ़ील्ड प्राप्त करने की आवश्यकता है क्योंकि आपको अभी तक पता नहीं है कि फ़ील्ड क्या मौजूद हैं (बहुत गतिशील डेटाबेस संरचना पर विचार करें)।

स्पष्ट फ़ील्ड नामों का उपयोग करने का एक और नुकसान यह है कि यदि उनमें से कई हैं और वे लंबे हैं तो यह कोड पढ़ना और / या क्वेरी लॉग को बहुत कठिन बनाता है।

तो नियम यह होना चाहिए: यदि आपको सभी क्षेत्रों की आवश्यकता है, तो * का उपयोग करें, यदि आपको केवल एक सबसेट की आवश्यकता है, तो उन्हें स्पष्ट रूप से नाम दें।


2

परिणाम बहुत बड़ा है। यह SQL इंजन से क्लाइंट को उत्पन्न करने और भेजने के लिए धीमा है।

क्लाइंट साइड, जेनेरिक प्रोग्रामिंग वातावरण होने के कारण, परिणाम को फ़िल्टर करने और संसाधित करने के लिए डिज़ाइन नहीं किया जाना चाहिए (जैसे WHERE क्लॉज़, ORDER क्लॉज़), क्योंकि पंक्तियों की संख्या बहुत बड़ी हो सकती है (उदाहरण, लाखों पंक्तियों की संख्या)।


इसलिए यदि आपको वास्तव में सभी अलग-अलग स्तंभों का उपयोग करने की आवश्यकता है, तो यह ठीक होगा ... और यदि आपका डेटाबेस और ऐप एक ही सर्वर पर फिर से बैठे हैं, तो इससे बहुत फर्क नहीं पड़ता है?
अंकुर

@ अक्कुर: यहां तक ​​कि एक ही सर्वर पर डेटाबेस इंटरफेस पर डेटा संचारित करने की लागत होती है।
kennytm

2

आपके आवेदन में प्राप्त होने वाले प्रत्येक कॉलम का नामकरण यह भी सुनिश्चित करता है कि यदि कोई आपके टेबल अभी भी मौजूद है (किसी भी क्रम में), तो आपका एप्लिकेशन तब तक नहीं टूटेगा जब तक कि कोई टेबल बदल नहीं देता।


1

यह आपके DB सर्वर के संस्करण पर निर्भर करता है, लेकिन SQL के आधुनिक संस्करण किसी भी तरह से योजना को कैश कर सकते हैं। मैं कहूंगा कि आपके डेटा एक्सेस कोड के साथ जो भी सबसे ज्यादा कायम है, उसके साथ चलें।


1

एक कारण यह है कि तालिका के ढांचे में संभावित भविष्य के बदलावों के कारण आप जो कॉलम चाहते हैं, उसका सटीक अभ्यास करना बेहतर है।

यदि आप अपनी क्वेरी के परिणामों के साथ डेटा संरचना को पॉप्युलेट करने के लिए इंडेक्स आधारित दृष्टिकोण का उपयोग करके मैन्युअल रूप से डेटा पढ़ रहे हैं, तो भविष्य में जब आप एक कॉलम जोड़ते / हटाते हैं, तो आपके पास सिरदर्द होगा जो यह पता लगाने की कोशिश करेगा कि क्या गलत हुआ।

जैसा कि तेज है, मैं अपनी विशेषज्ञता के लिए दूसरों को निराश करूंगा।


1

अधिकांश समस्याओं के साथ, यह इस बात पर निर्भर करता है कि आप क्या हासिल करना चाहते हैं। यदि आप एक db ग्रिड बनाना चाहते हैं जो किसी भी तालिका में सभी कॉलमों की अनुमति देगा, तो "Select *" उत्तर है। हालाँकि, यदि आपको केवल कुछ कॉलमों की आवश्यकता होगी और क्वेरी से कॉलम जोड़ने या हटाने को बार-बार किया जाता है, तो उन्हें व्यक्तिगत रूप से निर्दिष्ट करें।

यह उस डेटा की मात्रा पर भी निर्भर करता है जिसे आप सर्वर से ट्रांसफर करना चाहते हैं। यदि स्तंभों में से एक को मेमो, ग्राफिक, ब्लॉब, आदि के रूप में परिभाषित किया गया है और आपको उस कॉलम की आवश्यकता नहीं है, तो आप "सेलेक्ट *" का उपयोग नहीं करेंगे या आपको डेटा का एक पूरा गुच्छा मिलेगा जो आप नहीं करते हैं चाहते हैं और आपके प्रदर्शन को नुकसान हो सकता है।


1

अन्य सभी ने जो कहा है, उसे जोड़ने के लिए, यदि आपके सभी कॉलम जो आप चुन रहे हैं, उन्हें एक इंडेक्स में शामिल किया गया है, तो आपका परिणाम सेट SQL से अतिरिक्त डेटा देखने के बजाय इंडेक्स से खींच लिया जाएगा।


1

सेलेक्ट * आवश्यक है यदि कोई मेटाडेटा प्राप्त करना चाहता है जैसे कि कॉलम की संख्या।


1

उपरोक्त सभी ने क्या कहा, इसके अलावा:

यदि आप पठनीय बनाए रखने योग्य कोड के लिए प्रयास कर रहे हैं, तो कुछ ऐसा करना:

फोंट का चयन करें, विगेट्स से बार;

तुरन्त पठनीय है और इरादा दिखाता है। यदि आप वह कॉल करते हैं तो आपको पता है कि आप क्या कर रहे हैं। यदि विगेट्स में केवल foo और bar कॉलम हैं, तो * सेलेक्ट करने का मतलब है कि आपको अभी भी सोचना है कि आपको क्या मिल रहा है, इस बात की पुष्टि करें कि ऑर्डर सही ढंग से मैप किया गया है, आदि, लेकिन अगर विजेट में अधिक कॉलम हैं, लेकिन आप केवल foo में रुचि रखते हैं और बार, तब आपका कोड गड़बड़ हो जाता है जब आप वाइल्डकार्ड के लिए क्वेरी करते हैं और उसके बाद केवल कुछ का उपयोग करते हैं।


1

और याद रखें कि यदि आपके पास परिभाषा से एक आंतरिक जुड़ाव है, तो आपको सभी स्तंभों की आवश्यकता नहीं है क्योंकि जुड़ने वाले कॉलम में डेटा दोहराया जाता है।

यह ऐसा नहीं है कि SQl सर्वर में कॉलम को सूचीबद्ध करना कठिन है या समय लेने वाला भी है। आप बस उन्हें ऑब्जेक्ट ब्राउज़र से खींच सकते हैं (आप शब्द कॉलम से खींचकर सभी को एक बार में प्राप्त कर सकते हैं)। अपने सिस्टम पर एक स्थायी प्रदर्शन हिट करने के लिए (इसे जारी करें क्योंकि यह अनुक्रमित और बेवस्यू का उपयोग नेटवर्क पर अनावश्यक डेटा भेजना कम कर सकता है) और यह अधिक संभावना है कि आपको अप्रत्याशित समस्याएं होंगी क्योंकि डेटाबेस में परिवर्तन होता है (कभी-कभी कॉलम मिलते हैं) आप नहीं चाहते कि उपयोगकर्ता उदाहरण के लिए देखें) विकास के समय के एक मिनट से कम समय बचाने के लिए अदूरदर्शी और अव्यवसायिक है।


1

प्रदर्शन के लिहाज से मैंने टिप्पणी देखी है कि दोनों समान हैं। लेकिन प्रयोज्य पहलू कुछ + और-के हैं

जब आप एक क्वेरी में (चयन *) का उपयोग करते हैं और यदि कोई तालिका में परिवर्तन करता है और नए फ़ील्ड जोड़ता है जिसे पिछली क्वेरी की आवश्यकता नहीं है तो यह एक अनावश्यक ओवरहेड है। और क्या होगा अगर नया जोड़ा गया क्षेत्र एक बूँद या एक छवि क्षेत्र है ??? आपकी क्वेरी प्रतिक्रिया समय वास्तव में तब धीमा होने वाला है।

दूसरे हाथ में अगर आप एक का चयन करते हैं (col1, col2, .. का चयन करें) और यदि तालिका बदल जाती है और नए फ़ील्ड जोड़े जाते हैं और यदि परिणाम सेट में उन फ़ील्ड की आवश्यकता होती है, तो आपको तालिका परिवर्तन के बाद हमेशा अपने चयनित क्वेरी को संपादित करने की आवश्यकता होती है।

लेकिन मेरा सुझाव है कि हमेशा अपने प्रश्नों में से col1, col2, ... का उपयोग करें और यदि तालिका बाद में बदल जाती है तो क्वेरी को बदल दें ...


0

उन कॉलमों को बिल्कुल परिभाषित करें जिन्हें आप हर बार चुनना चाहते हैं। कोई कारण नहीं है और प्रदर्शन में सुधार इसके लायक है।

उन्हें "SELECT *" का विकल्प कभी नहीं देना चाहिए था


0

यदि आपको हर कॉलम की आवश्यकता है तो अभी SELECT * का उपयोग करें लेकिन याद रखें कि जब आप परिणाम का उपयोग कर रहे हैं तो क्रम में संभावित रूप से परिवर्तन हो सकता है और न कि सूचकांक द्वारा उनका उपयोग करें।

मैं टिप्पणियों के बारे में उपेक्षा करूंगा कि कैसे * सूची प्राप्त करने की आवश्यकता है - संभावनाएं नामांकित हैं और नामांकित कॉलम को सत्यापित करना अधिक होने पर प्रसंस्करण समय के बराबर है। समय से पहले अनुकूलन न करें ;-)


0

निष्पादन दक्षता के संदर्भ में मुझे किसी महत्वपूर्ण अंतर की जानकारी नहीं है। लेकिन प्रोग्रामर दक्षता के लिए मैं खेतों के नाम लिखूंगा क्योंकि

  • आप क्रम को जानते हैं, यदि आपको संख्या द्वारा अनुक्रमित करने की आवश्यकता है, या यदि आपका ड्राइवर बूँद-मानों पर अजीब व्यवहार करता है, और आपको एक निश्चित क्रम की आवश्यकता है
  • आप केवल उन फ़ील्ड्स को पढ़ते हैं जिनकी आपको आवश्यकता है, यदि आपको कभी और फ़ील्ड जोड़ना चाहिए
  • यदि आप किसी फ़ील्ड को गलत करते हैं या नाम बदलते हैं, तो आप एक sql- त्रुटि प्राप्त करते हैं, न कि किसी रिकॉर्डसेट / पंक्ति से रिक्त मान
  • आप बेहतर पढ़ सकते हैं कि क्या हो रहा है।

0

हे, व्यावहारिक हो। प्रोटोटाइपिंग करते समय सेलेक्ट * का उपयोग करें और कार्यान्वयन और तैनाती के समय विशिष्ट कॉलम का चयन करें। एक निष्पादन योजना के दृष्टिकोण से, दोनों आधुनिक प्रणालियों पर अपेक्षाकृत समान हैं। हालाँकि, विशिष्ट कॉलम का चयन करने से डेटा की मात्रा सीमित हो जाती है जिसे डिस्क से पुनर्प्राप्त करना पड़ता है, मेमोरी में संग्रहीत होता है और नेटवर्क पर भेजा जाता है।

अंत में सबसे अच्छी योजना विशिष्ट कॉलम का चयन करना है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.