2009-05-12 15 views
6

अगर मैं दो प्रश्नोंस्तंभों की संख्या एक प्रश्न की गति को प्रभावित लौटे करता है?

SELECT Id, Forename, Surname 
FROM Person 
WHERE PersonName Like(‘%frank%’) 

और

SELECT * 
FROM Person 
WHERE PersonName Like(‘%frank%’) 

कौन सा क्वेरी तेजी से चलेंगे है? क्या क्लॉज/टेबल सबसे बड़ा कारक शामिल है, या कॉलम की संख्या लौटा दी गई है?

मैं पूछ रहा हूं क्योंकि मैं ऑब्जेक्ट्स की श्रृंखला बना रहा हूं जो डेटाबेस टेबल पर मैप करता है। आम तौर पर प्रत्येक वस्तु होगा कम से कम इन तीन तरीकों:

Select - चुनता सब कुछ

List - पर्याप्त का चयन करता है कि एक ड्रॉपडाउन सूची

Search पॉप्युलेट करने के लिए इस्तेमाल किया जा सकता - सब कुछ है कि में देखी जा सकती है का चयन करता है परिणाम, आमतौर पर लगभग 6 या तो कॉलम।

यदि प्रत्येक क्वेरी कॉलम के एक ही सेट को वापस लौटाती है तो कोड के रखरखाव और परीक्षण को और अधिक छोटा होना चाहिए। डेटाबेस किसी भी तालिका में 50,000 पंक्तियां ऊपर प्राप्त करने के लिए की संभावना नहीं है, इसलिए यदि प्रदर्शन में अंतर छोटा है तो मैं विकास समय में बचत ले लेंगे। यदि प्रदर्शन मंजिल के माध्यम से गिरने जा रहा है, तो मैं एक अलग कोण से काम करूंगा।

तो, विकास की आसानी के लिए, SELECT * समझदार है, या यह मूर्ख है?

+3

बस थोड़ा सा व्याकरण: * एक क्वेरी की गति को प्रभावित करता है। –

+0

http://xkcd.com/326/ – Quassnoi

+0

विदेश नीति कुछ प्रभावित कर सकती है, लेकिन कई कॉलम – Andomar

उत्तर

23

बेहतर होगा कि तुम से बचने के लिए जब आप तालिका लेआउट बदलने SELECT *

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

मैं आपके अधिकांश बिंदुओं से सहमत हूं लेकिन "कॉलम डुप्लिकेट नाम प्राप्त कर सकते हैं" - यह मेरे लिए ख़बर है। ऐसा कैसे? – paxdiablo

+2

@ पैक्स: यदि आपके पास क्वेरी के अंदर स्वयं-जुड़ना है, या दो तालिकाओं में शामिल हों जिनमें समान नाम वाले कुछ कॉलम हैं। – Quassnoi

+0

@ पैक्स का चयन करें * व्यक्ति पी से, संपर्क सी कहां c.PersonID = p.PersonID; इसका सामान्य रूप से 2 टेबल में [नाम] होगा उदाहरण के लिए – balexandre

-2

निश्चित रूप से। उन कॉलम का बेहतर नाम जिन्हें आप पुनर्प्राप्त करना चाहते हैं।

0

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

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

0

मैं "चयन *" निर्माण का उपयोग क्यों करते हुए इस question पर जाऊंगा।

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

0

आम तौर पर, किसी भी स्थिति में, आप अपने कोड में

SELECT * FROM TABLE 

का उपयोग करने से दूर रहने के लिए चाहते हैं। ऐसा करने से कई मुद्दों का कारण बन सकता है, जिनमें से केवल एक प्रदर्शन है। दो अन्य मैं अपने सिर के ऊपर से सोचने के बारे में सोच सकता हूं संसाधन उपयोग (यदि आप कॉलम का चयन कर रहे हैं जिनकी आपको आवश्यकता नहीं है, या कोई बाद में कॉलम जोड़ता है ... आप डेटा वापस ला रहे हैं और स्मृति बर्बाद कर रहे हैं) और कोड पठनीयता (अगर कोई आपके कोड में से * चुनें * ... यह आवश्यक नहीं है कि आपके आवेदन में कौन से कॉलम वास्तव में उपयोग किए जा रहे हैं)।

बस कुछ चीजों के बारे में सोचने के लिए ... लेकिन सबसे अच्छा अभ्यास इसका उपयोग नहीं करना है।

0

हां यह करता है। मूल रूप से:

  • अधिक डेटा
  • डेटाबेस सर्वर और अधिक डेटा

आप उपयोग नहीं करना चाहिए लाने के लिए है अपने डेटाबेस सर्वर से स्थानांतरित किए जाने की है का चयन करें *

0

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

मेरा मानना ​​है कि मैंने उन मामलों को भी देखा है जहां चयन * को वास्तव में एक तालिका में प्राप्त किया जाना चाहिए, क्योंकि केवल उस तालिका पर इंडेक्स का उपयोग करने के विरोध में समग्र परिणाम सेट को कम करने में मदद करने के लिए। हालांकि, मैं इसका एक उदाहरण नहीं सोच सकता।

1

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

6

SELECT * आमतौर पर कभी भी एक अच्छा विचार नहीं है। यह आपके डीबीएमएस को बहुत कम नहीं कर सकता है, लेकिन संभवतः नेटवर्क की आवश्यकता के मुकाबले ज्यादा डेटा प्रसारित हो जाएगा।

हालांकि, LIKE '%frank%' खंड के उपयोग से यह महत्वहीनता में घुसने की संभावना है जो मूल रूप से गैर-अनुक्रमणीय है और परिणामस्वरूप पूर्ण तालिका स्कैन होगा।

आप डेटा को साफ करने पर विचार करना चाहेंगे क्योंकि यह डेटाबेस में प्रवेश करता है क्योंकि इससे निश्चित रूप से बाद के प्रश्नों को बहुत तेजी से चलाया जाएगा।

select x,y,z from table where name = 'frank' 

आप फ्रेंकलिन प्राप्त करने के लिए के रूप में अच्छी तरह से चाहते हैं, उपयोग:

आप खुलकर के बाद कर रहे हैं, तो यकीन है कि यह स्पष्ट और प्रयोग के रूप में संग्रह किया गया है बनाने के

select x,y,z from table where name like 'frank%' 

इन दोनों जाएगा नाम कॉलम पर एक इंडेक्स का उपयोग करने में सक्षम हो, "%frank%" नहीं होगा।

0

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

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

तो सामान्य रूप से आपको इसका उपयोग नहीं करना चाहिए। अधिकांश ऑब्जेक्ट रिलेशनल मैपिंग टूल्स एसक्यूएल उत्पन्न करते हैं जिसमें सभी कॉलम नाम होते हैं, इसलिए विकास के दौरान यह संभवतः कोई मुद्दा नहीं है। मैं व्यक्तिगत रूप से केवल त्वरित विज्ञापन-प्रसार क्वेरी के लिए उपयोग करता हूं जिसे मुझे मैन्युअल रूप से लिखना है।

1

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

नोट ओरेकल अवधारणाओं पुस्तिका का निम्नलिखित उदाहरण:

पंक्ति स्वरूप और आकार ओरेकल भंडार एक या अधिक पंक्ति टुकड़ों के रूप में कम से कम 256 स्तंभों के लिए डेटा वाली एक डेटाबेस तालिका में से प्रत्येक पंक्ति। यदि एक पूरी पंक्ति को एक ही डेटा ब्लॉक में डाला जा सकता है, तो ओरेकल पंक्ति को एक पंक्ति टुकड़ा के रूप में संग्रहीत करता है। हालांकि, अगर एक पंक्ति के डेटा के सभी के लिए एक अद्यतन एक एकल डेटा ब्लॉक में या यदि प्रविष्ट नहीं हो पाता कोई मौजूदा पंक्ति को पंक्ति अपने डेटा ब्लॉक विकसित हो जाना का कारण बनता है, तो ओरेकल भंडार पंक्ति में एकाधिक पंक्ति टुकड़े का उपयोग कर। डेटा ब्लॉक में आमतौर पर प्रत्येक पंक्ति के लिए केवल एक पंक्ति टुकड़ा होता है। जब ओरेकल को से अधिक पंक्ति में एक पंक्ति को स्टोर करना होगा, तो यह एकाधिक ब्लॉक में बंधे हुए हैं।

जब एक तालिका में 255 से अधिक कॉलम, पंक्तियाँ है 255 वां स्तंभ के बाद डेटा की संभावना है है एक ही ब्लॉक के भीतर श्रृंखलित किया जाना है। इसे इंट्रा-ब्लॉक चेनिंग कहा जाता है। एक जंजीर पंक्ति के टुकड़े टुकड़ों के पंक्तियों का उपयोग करके एक साथ बंधे होते हैं। इंट्रा-ब्लॉक चेनिंग के साथ, उपयोगकर्ताओं को एक ही ब्लॉक में सभी डेटा प्राप्त होता है। यदि पंक्ति ब्लॉक में फिट बैठती है, तो उपयोगकर्ताओं को I/O प्रदर्शन में प्रभाव दिखाई नहीं देता है, क्योंकि कोई अतिरिक्त I/O ऑपरेशन शेष पंक्ति को पुनर्प्राप्त करने के लिए आवश्यक है।

हालांकि: यदि 400 स्तंभ हैं, मैं शर्त है कि अधिकांश पंक्तियां एक ब्लॉक में फ़िट नहीं होगा और इसलिए आप एक बहुत अधिक 'db फ़ाइल अनुक्रमिक पढ़ा' सामान्य रूप से आवश्यक से देखेंगे। साथ ही, मैं याद करता हूं कि स्टीव एडम्स (या कोई बहुत पहले) उल्लेख करते हैं कि कॉलम "सूची नीचे और नीचे" तक पहुंचने के लिए अतिरिक्त लागत है - क्षमा करें उस लिंक को नहीं है।

+0

क्या यह एमएस एसक्यूएल पर भी लागू होता है? – ilivewithian

2

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

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

यह सही तरीका है और सबसे इष्टतम है। इसका कारण यह है कि आपके डेटा को इकट्ठा करने के लिए केवल इतना ही आवश्यक है कि आप अपने परिणाम प्राप्त करने से पहले डेटा को संग्रहीत करने में सही स्थान (आपको क्या चाहिए) ले लें।

SELECT Id, Forename, Surname 
FROM Person 
WHERE PersonName Like(‘%frank%’) 

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

SELECT * 
FROM Person 
WHERE PersonName Like(‘%frank%’) 
2

छोटी परियोजनाओं के लिए, आप आमतौर पर select * के साथ भाग प्राप्त कर सकते हैं। हालांकि, ऐसा करने के लिए यह "सही" है। आपको गैर-इंडेक्स क्वेरी में एक तालिका के लिए कोई सराहनीय गति अंतर नहीं दिखाई देगा ... केवल एक चीज जो आप सराहना कर रहे हैं वह कॉलम के लिए अधिक बैंडविड्थ का उपयोग कर रही है जिसे आप नहीं पढ़ते हैं।

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

Select * हालांकि उपयोग करता है, और यदि आप इसे ठीक से उपयोग (जैसे कि, एक कैश के साथ संयोजन में, बनाने यकीन है कि यह select table.* है, और स्तंभ नाम के आधार पर परिणामों को संबोधित) आप अपने आवेदन द्वारा किए गए प्रश्नों को कम कर सकते हैं।

5

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

हालांकि, कुछ एसक्यूएल इंजन (निश्चित रूप से एमएस-एसक्यूएल) चुनिंदा * कैश करेंगे, इसलिए यदि आप एक तैयार कथन का उपयोग कर रहे हैं, या एक दृश्य या संग्रहीत प्रक्रिया है, और, तालिका स्कीमा को बदलें, यह तब तक नहीं बदलेगा जब तक कि दृश्य या एसपी को पुन: संकलित नहीं किया जाता है, इसलिए यदि आप इन प्रश्नों को गतिशील रूप से नहीं चला रहे हैं तो ऐसा करने का एक अच्छा कारण है।

और निश्चित रूप से, यह डेटाबेस इंजन द्वारा भिन्न होता है, इसलिए यह सुनिश्चित करने के लिए कि हिट स्पष्ट रूप से बड़ा नहीं है, थोड़ा लोड परीक्षण होगा।

0

केवल समय मैं का उपयोग करें "select *" नहीं घटना वास्तव में एक "select *"

विशेष रूप से है: नहीं है कि एक ही

select count(*) from table

select count(ID) from table

के रूप में पहले तालिकामें पंक्तियों की संख्या देता है 0 लेकिन दूसरा पंक्तियों की संख्या को नॉट नल आईडी मान के साथ देता है।

एक सूक्ष्म भेद लेकिन याद रखने लायक है।

+0

SELECT * का एक और स्वीकार्य उपयोग EXISTS क्लॉज के सबक्वायरी में है। – onedaywhen

0

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

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

यह राशि को कम करेगा डेटा नहीं दिया और यह एक छोटे बनाता है अधिक पठनीय।

0

मुझे शैतान वकील खेलते हैं और एक परिदृश्य का सुझाव देते हैं जहां चयन * बेहतर विकल्प है। मान लीजिए कि आप एक यूजर इंटरफेस बना रहे हैं जहां आप डेटासेट के परिणाम लेते हैं और इसे टेबल या ग्रिड के किसी रूप में प्रदर्शित करते हैं। आप डेटासेट में कॉलम से मेल खाने के लिए यूआई में कॉलम बना सकते हैं और चयन * MyView से कर सकते हैं।

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

बस सोचा कि मैं इसे जोड़ दूंगा क्योंकि कभी-कभी लोग कुछ नियमों का पालन करने के बारे में दयनीय हो जाते हैं और संदर्भ मामलों को भूल जाते हैं।

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