2008-10-16 6 views
23

का चयन करें मैं एमएस एसक्यूएल सर्वर 2005 का उपयोग कर रहा है कि वहाँ एक अंतर, एसक्यूएल इंजन के लिए है,वहाँ चयन के बीच एक अंतर * है और [सूची प्रत्येक स्तंभ]

SELECT * FROM MyTable; 

और

SELECT ColA, ColB, ColC FROM MyTable; 
के बीच

जब कोला, कोल्ब और कोल्सी तालिका में प्रत्येक कॉलम का प्रतिनिधित्व करते हैं?

यदि वे समान हैं, तो क्या कोई कारण है कि आपको किसी दूसरे का उपयोग क्यों करना चाहिए? मेरे पास एक प्रोजेक्ट है जो LINQ पर भारी है, और मुझे यकीन नहीं है कि मानक चयन * यह उत्पन्न करता है, यह एक बुरा अभ्यास है, या अगर मुझे हमेशा एक होना चाहिए। यह निर्दिष्ट करने के लिए कि कौन से कोल्स मैं चाहता हूं।

संपादित करें: "जब कोला, कोल्ब, और कोल्सी तालिका में सभी कॉलम हैं?" "जब कोला, कोल्ब, और कोल्सी तालिका में हर कॉलम का प्रतिनिधित्व करते हैं?" विस्तृत जानकारी के लिए।

+1

यह भी देखें: http://stackoverflow.com/questions/65512/which-is-faster-best-select-or-select-column1-colum2-column3-etc –

उत्तर

38

आम तौर पर, यह स्पष्ट होना बेहतर है, इसलिए Select col1, col2 from Table बेहतर है। कारण यह है कि किसी बिंदु पर, उस तालिका में एक अतिरिक्त कॉलम जोड़ा जा सकता है, और अनचाहे डेटा को क्वेरी से वापस लाया जाएगा।

हालांकि यह एक कठिन और तेज़ नियम नहीं है।

+2

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

+3

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

4

जब आप प्रत्येक फ़ील्ड को अलग-अलग चुनते हैं, तो यह स्पष्ट होता है कि वास्तव में कौन से फ़ील्ड चुने जा रहे हैं।

17

1) दूसरा एक कॉलम लौटाए जाने के बारे में अधिक स्पष्ट है। दूसरे के मूल्य यह है कि आप स्पष्ट रूप से यह जानना चाहते हैं कि कौन से कॉलम वापस आते हैं।

2) इसमें स्पष्ट रूप से उपयोग किए जाने वाले लोगों की तुलना में अधिक कॉलम होने पर संभावित रूप से कम डेटा लौटाया जा सकता है।

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

4

कुछ कारणों पहले बयान का उपयोग नहीं (चयन *) कर रहे हैं:

  1. आप कुछ बड़े क्षेत्रों जोड़ देते हैं तो बाद में उस मेज पर, आप जा सकते थे (ब्लॉब स्तंभ बहुत बुरा होगा) प्रदर्शन की समस्याओं आवेदन
  2. में पीड़ित हैं क्वेरी दो या अधिक टेबल के साथ एक में शामिल हों-क्वेरी था, में से कुछ फ़ील्ड एक ही नाम हो सकता था। यह सुनिश्चित करना बेहतर होगा कि आपके क्षेत्र के नाम अलग हैं।
  3. क्वेरी की उद्देश्य एक प्रोग्रामिंग सौंदर्यशास्र दृष्टिकोण
8

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

+0

हां! इंडेक्स को स्पष्ट करने के लिए यह सबसे अच्छा कारण है। –

+0

स्वीकृत उत्तर * और col1, col2, col3 के बीच के अंतर के बारे में अधिक लोगों की [गलत] धारणाओं को पूरा करने लगता है। – ProfK

1

क्वेरी निष्पादन योजना पर एक त्वरित नज़र से पता चलता है कि क्वेरी समान हैं।

अंगूठे का सामान्य नियम है कि आप केवल क्षेत्रों है कि आप वापस आ जरूरत करने के लिए अपने प्रश्नों को सीमित करना चाहते जाएगा।

2

आगे-compatiblity के लिए यह अच्छा है।

जब आप का उपयोग

SELECT * FROM myTable 

और "mytable" में 3 स्तंभ हैं। आपको

SELECT Column1, Column2, Column3 FROM myTable 

पर एक ही परिणाम मिलते हैं लेकिन यदि आप भविष्य में नया कॉलम जोड़ते हैं, तो आपको एक अलग परिणाम मिलते हैं।

बेशक

, यदि आप नाम मौजूदा स्तंभ में से एक बदलने के लिए, पहले मामले में आप परिणाम प्राप्त और दूसरे मामले में आप एक त्रुटि मिलती है (मुझे लगता है, इस आवेदन के सही व्यवहार है)।

+1

मुझे यकीन नहीं है कि भविष्य में परिवर्तन होने पर तोड़ना आगे संगतता की परिभाषा है। –

+0

मुझे लगता है कि टीसीके का मामला यह है कि काम करने का नाटक करने से ब्रेकिंग बेहतर है (लेकिन काम नहीं कर रहा है)। –

+2

मैं सहमत हूं, यदि आप स्तंभ का नाम बदलते हैं और कॉलम नाम से पहुंच परिणामों का नाम बदलते हैं तो ऐप को तोड़ना चाहिए। * यदि आप अभी भी इंडेक्स के बजाय कॉलम नाम से परिणामों तक पहुंचते हैं तो नाम बदलने के खिलाफ स्वयं को सुरक्षित रखने में कोई बेहतर नहीं है। – Josh

1
LinqToSql लिए

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

3

SELECT * अधिकांश स्थानों में एक खराब अभ्यास है।

  • क्या होगा यदि कोई उस तालिका में 2 जीबी ब्लॉब कॉलम जोड़ता है?
  • कोई उस तालिका में वास्तव में कोई कॉलम जोड़ता है?

यह एक बग होने की प्रतीक्षा कर रहा है।

+0

"चयन *" 2 गीगा वापस नहीं करेगा, इसलिए यह अप्रासंगिक है। यह पठनीयता और स्पष्टीकरण के साथ निर्भर कोड को प्रभावित करने वाले स्तंभों का जोड़ है जो वास्तव में मायने रखता है। –

+0

मैं बग भाग को छोड़कर ज्यादातर सहमत हूं। मुझे लगता है कि मैंने पूरी पंक्ति प्राप्त करके और केवल उस स्थान को संभालने के लिए केवल एक स्थान (डेटा एक्सेस लेयर क्लास) प्राप्त करके बग से बचा है। मैं आमतौर पर वहां संभावित मुद्दों को संभालता हूं। एसक्यूएल के लिंक के साथ डेटा मॉडल क्लासेस सामान को ट्विक करने के लिए एक बेहतरीन जगह है। – stephenbayer

+0

@ पी डीबीए: क्या मैंने कहा कि यह 2 गीगा वापस करेगा? मैं केवल यह पूछ रहा था कि कोड दूसरे बुलेट में दिखाए गए अनुसार तालिका में बदलाव को संभालेगा या नहीं। @ एसबी आप स्कीमा में बदलावों के आसपास कोड कर सकते हैं, अधिकांश देवता नहीं करते हैं और चीजें तोड़ती हैं। अपने आप को इस मौके पर क्यों खुलें कि ऐसा होगा? –

1

यह आप "अंतर" द्वारा क्या मतलब है पर निर्भर करता है। स्पष्ट वाक्यविन्यास अंतर है, लेकिन वास्तविक अंतर प्रदर्शन में से एक है।

जब आप कहते हैं कि SELECT * FROM MyTable, आप SQL क्वेरी इंजन कि तालिका में कॉलम के सभी के साथ एक डेटा सेट वापस जाने के लिए, कह रहे हैं, जबकि SELECT ColA, ColB, ColC FROM MyTable क्वेरी इंजन बताता है केवल कोला, ColB के साथ एक डेटा सेट वापस जाने के लिए , और मेज से ColC।

आप 100 कॉलम CHAR [10] के रूप में परिभाषित के साथ एक मेज है कहो। SELECT * 100 कॉलम * 10 बाइट्स डेटा के डेटा लौटाएगा जबकि SELECT ColA, ColB, ColC डेटा के 3 कॉलम * 10 बाइट्स डेटा लौटाएगा। यह तार भर में वापस जा रहे डेटा की मात्रा में एक बड़ा आकार अंतर है।

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

+1

इस मामले में, प्रदर्शन में कोई अंतर नहीं है। मेरा मानना ​​है कि आपने प्रश्न के पहले भाग में जानकारी के इस महत्वपूर्ण टुकड़े को याद किया: "जब कोला, कोल्ब और कोल्सी तालिका में सभी कॉलम हैं?" चूंकि वह सभी कॉलम चाहता है, इसमें कोई प्रदर्शन अंतर नहीं है। अन्य मामले? हाँ। –

+0

@ पिट्सबर्ग डीबीए: मैंने इसे देखा लेकिन इसे अलग-अलग पढ़ा ... क्योंकि कोला, कोल्ब और कोल्सी तालिका में सभी कॉलम हैं कि वे तालिका में कॉलम का पूरा सेट नहीं थे। किसी भी तरह से, मेरी प्रतिक्रिया में जानकारी अभी भी प्रासंगिक है (लेकिन इस _specific_ मामले में, यह धो है।) –

0

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

9

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

+0

मुझे नहीं लगता कि आपको बहुत रक्षात्मक होना है। यह एक स्टाइलिस्टिक रूप से व्यक्तिपरक प्रश्न का एक वैध जवाब है। :) –

+0

विकास पक्ष पर "क्विकर", निश्चित रूप से। हालांकि, आप अपने चयन विवरणों में से लगभग हर एक पर I/O बर्बाद कर सकते हैं। –

+1

मैं आपके साथ हूं, और मुझे अभी तक एक प्रदर्शन समस्या में आना है जिसे "चयन *" बनाम "वापस कॉलम 1, कॉलम 2 ..." पर देखा जा सकता है। मुझे यकीन है कि ऐसा होता है, लेकिन जब मैं 99% समय की आवश्यकता नहीं होती तो इसके खिलाफ रक्षात्मक कोड से होने पर मैं उस अपवाद से निपटना चाहता हूं। – JasonS

2

यदि आपका कोड किसी निश्चित क्रम में कुछ कॉलम पर निर्भर करता है, तो आपको कॉलम सूचीबद्ध करने की आवश्यकता है। यदि नहीं, तो यदि आप "*" का उपयोग करते हैं या चयन कथन में कॉलम नाम लिखते हैं तो यह वास्तव में कोई फर्क नहीं पड़ता है।

एक उदाहरण यह है कि यदि आप किसी तालिका में कॉलम डालते हैं। कोला ColB ColC

आप एक प्रश्न हो सकता है::

इस तालिका लो

SELECT * 
FROM myTable 

तो कोड हो सकता है:

rs = executeSql("SELECT * FROM myTable") 
while (rs.read()) 
    Print "Col A" + rs[0] 
    Print "Col B" + rs[1] 
    Print "Col C" + rs[2] 

आप ColB और जो कॉलम जोड़ें ColC, क्वेरी जो आप खोज रहे हैं उसे वापस नहीं लौटाएगी। इसलिए यदि आप परिणाम संग्रह आप गलत स्तंभ पर नजर रखेंगे, के सूचकांक # द्वारा निर्धारित का उल्लेख

1
SELECT * FROM MyTable 

चयन * स्कीमा में स्तंभ क्रम पर निर्भर है।

SELECT Col1,Col2,Col3 FROM MyTable 

इस क्वेरी आप एक संग्रह है कि समय के साथ ही रहता है, लेकिन कितनी बार आप स्तंभ क्रम वैसे भी बदल रहे हैं दे देंगे?

3

कुछ बातें:

  • लोगों की एक अच्छी संख्या में यहाँ पोस्ट किया है * उपयोग करने के खिलाफ की सिफारिश, और दिए जाने वाले सम्मान जवाब के लिए कई अच्छे कारणों। अब तक 10 अन्य प्रतिक्रियाओं में से केवल एक सूची कॉलम की अनुशंसा नहीं करता है।
  • लोग अक्सर उस नियम के अपवाद करते हैं जब StackOverflow जैसी साइटों की सहायता करते हैं, क्योंकि वे अक्सर नहीं जानते कि आपकी तालिका में कौन से कॉलम हैं या आपकी क्वेरी के लिए महत्वपूर्ण हैं। इसी कारण से, आपको वेब पर कहीं और बहुत सारे कोड दिखाई देंगे जो * सिंटैक्स का उपयोग करता है, भले ही पोस्टर इसे अपने कोड में टालना चाहें।
9

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

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

यदि आप किसी ऑब्जेक्ट के लिए बैकिंग स्टोर के रूप में अपनी तालिका का उपयोग कर रहे हैं (जो कि LINQ-to-SQL केस में दिखाई देता है), तो संभवतः आप इस तालिका में जोड़े गए किसी भी नए कॉलम को अपनी ऑब्जेक्ट में शामिल करना चाहते हैं, और इसके विपरीत -versa। आप उन्हें समानांतर में बनाए रख रहे हैं। इस कारण से, इस मामले के लिए, * चयन खंड में विनिर्देश सही है। स्पष्ट विनिर्देश आपको प्रत्येक बार कुछ बदलते समय रखरखाव का एक अतिरिक्त बिट देगा, और एक बग अगर आपने फ़ील्ड सूची को सही तरीके से अपडेट नहीं किया है।

यदि क्वेरी बहुत सारे रिकॉर्ड वापस करने जा रही है, तो संभवतः आप प्रदर्शन कारणों के लिए स्पष्ट विनिर्देश के साथ बेहतर हैं।

यदि दोनों चीजें सत्य हैं, तो दो अलग-अलग प्रश्न पूछने पर विचार करें।

0

एक उदाहरण के रूप में आप क्यों नहीं (imho) चयन * का उपयोग करना चाहिए। यह MSSQL से संबंधित नहीं है, बल्कि MySQL से संबंधित है। 5.0.12 से पहले के संस्करणों ने कुछ प्रकार के जॉइन से किसी भी मानक तरीके से कॉलम वापस नहीं किए। बेशक, यदि आपके प्रश्न परिभाषित करते हैं कि आप कौन से कॉलम चाहते हैं और किस क्रम में आपको कोई समस्या नहीं है। अगर वे नहीं करते हैं तो मजा की कल्पना करो।

(एक संभावित अपवाद: आपकी क्वेरी सिर्फ एक मेज से चयन करता है और आप स्थिति नाम के बजाय द्वारा अपनी पसंद के प्रोग्रामिंग भाषा में स्तंभों की पहचान।)

0

"* का चयन करें" का उपयोग प्रोग्रामर टाइपिंग के लिए अनुकूलित करता है। बस। यही एकमात्र फायदा है।

संबंधित मुद्दे