सेलेक्ट * को हानिकारक क्यों माना जाता है?


256

SELECT *बुरी प्रथा क्यों है ? यदि आप चाहते थे कि एक नया कॉलम जोड़ा जाए तो क्या इसका मतलब कम कोड को बदलना नहीं होगा?

मैं समझता हूं कि SELECT COUNT(*)कुछ DB पर एक प्रदर्शन समस्या है, लेकिन क्या होगा यदि आप वास्तव में हर कॉलम चाहते हैं?


30
SELECT COUNT(*)बुरा होना अविश्वसनीय रूप से पुराना और पुराना है । जानकारी के लिए SELECT *- देखें: stackoverflow.com/questions/1960036/…
OMG Ponies

8
SELECT COUNT(*)SELECT COUNT(SomeColumn)जब तक कॉलम नॉट नॉट कॉलम न हो, तब तक एक अलग उत्तर देता है । और आशावादी SELECT COUNT(*)विशेष उपचार दे सकता है - और आमतौर पर करता है। यह भी ध्यान दें कि WHERE EXISTS(SELECT * FROM SomeTable WHERE ...)विशेष केस उपचार दिया जाता है।
जोनाथन लेफ्लर

3
@ मिचेल मोर्ज़ेक, वास्तव में यह सवाल का उलटा है। मैं यह पूछ रहा हूं कि क्या यह कभी हानिकारक है, यदि यह कभी हानिकारक नहीं था।
थियोडोर आर। स्मिथ

1
@ बायब्रो निंजा: विशेष रूप से, MySQL इंजन के साथ MySQL में COUNT (*) के लिए एक अनुकूलन है: mysqlperformanceblog.com/2007/04/10/count-vs-countcol
पिस्कॉर ने

जवाबों:


312

वास्तव में तीन प्रमुख कारण हैं:

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

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

  • बाइंडिंग प्रॉब्लम। जब आप * का चयन करते हैं, तो दो अलग-अलग तालिकाओं से एक ही नाम के दो कॉलम को पुनः प्राप्त करना संभव है। यह अक्सर आपके डेटा उपभोक्ता को क्रैश कर सकता है। एक क्वेरी की कल्पना करें जो दो तालिकाओं में मिलती है, दोनों में "आईडी" नामक एक कॉलम होता है। एक उपभोक्ता को कैसे पता चलेगा कि कौन सा था? चयन करें * अंतर्निहित तालिका संरचनाओं को बदलने पर दृश्य (कम से कम कुछ संस्करणों SQL सर्वर में) को भी भ्रमित कर सकते हैं - दृश्य का पुनर्निर्माण नहीं किया जाता है, और जो डेटा वापस आता है वह बकवास हो सकता है । और इसका सबसे बुरा हिस्सा यह है कि आप अपने कॉलम का नाम रख सकते हैं, जो भी आप चाहते हैं, लेकिन अगले आदमी जो साथ आता है, उसे यह जानने का कोई तरीका नहीं हो सकता है कि उसे एक कॉलम जोड़ने के बारे में चिंता करनी होगी जो आपके पहले से विकसित के साथ टकराएगा नाम।

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

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

  • जब * का अर्थ "एक पंक्ति" है। निम्नलिखित उपयोग के मामलों में, SELECT * बस ठीक है, और अफवाहें हैं कि यह एक प्रदर्शन हत्यारा है सिर्फ शहरी किंवदंतियां हैं जो कई साल पहले कुछ वैधता हो सकती थीं, लेकिन अब नहीं:

    SELECT COUNT(*) FROM table;

    इस मामले में, * का अर्थ है "पंक्तियों को गिनें"। यदि आप * के बजाय एक कॉलम नाम का उपयोग करते हैं, तो यह उन पंक्तियों की गणना करेगा जहां उस कॉलम का मान शून्य नहीं था । COUNT (*), मेरे लिए, वास्तव में उस अवधारणा को चलाती है जिसे आप पंक्तियों की गिनती कर रहे हैं , और आप NULL द्वारा अपने समुच्चय से निकाले जाने के कारण होने वाले अजीब धार वाले मामलों से बचते हैं।

    इस प्रकार की क्वेरी के साथ एक ही जाता है:

    SELECT a.ID FROM TableA a
    WHERE EXISTS (
        SELECT *
        FROM TableB b
        WHERE b.ID = a.B_ID);

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


17
"Select id, name" का उपयोग करने के लिए "SELECT *" के रूप में संभव है कि जुड़वाओं का उपयोग करते समय दो अलग-अलग तालिकाओं से एक ही नाम के दो कॉलम का चयन करें। तालिका नाम के साथ प्रीफ़िक्सिंग दोनों मामलों में समस्या को हल करती है।
मिशेल तातारीज़िकज़

1
मुझे पता है कि यह अधिक पुराना है, लेकिन यह वही है जिसे गुगली करते समय खींचा गया था इसलिए मैं पूछ रहा हूं। "जब मेरा मतलब है" एक पंक्ति "। निम्नलिखित उपयोग के मामलों में, SELECT * सिर्फ ठीक है, और अफवाहें हैं कि यह एक प्रदर्शन हत्यारा है सिर्फ शहरी किंवदंतियां हैं ..." क्या आपके पास यहां कोई संदर्भ है? क्या यह कथन हार्डवेयर के अधिक शक्तिशाली होने के कारण है (यदि ऐसा मामला है तो इसका मतलब यह नहीं है कि यह अक्षम नहीं है कि आप नोटिस करने की संभावना कम है)। मैं प्रति सेकेंड अनुमान लगाने की कोशिश नहीं कर रहा हूं मैं सोच रहा हूं कि यह कथन कहां से आता है।
जेरेड

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

4
उपयोग करने *का एक और लाभ यह है कि कुछ स्थितियों में यह MySQL के कैश सिस्टम का बेहतर लाभ उठा सकता है। यदि आप बड़ी संख्या में समान selectक्वेरी चला रहे हैं, जो विभिन्न कॉलम नामों ( select A where X, select B where X...) का अनुरोध करते हैं , select * where Xतो कैश का उपयोग करके बड़ी संख्या में क्वेरी को संभाल सकते हैं, जिसके परिणामस्वरूप पर्याप्त प्रदर्शन को बढ़ावा मिल सकता है। यह एक एप्लिकेशन-विशिष्ट परिदृश्य है, लेकिन यह ध्यान में रखने योग्य है।
बेन डी

2
8+ साल बाद, लेकिन अस्पष्टता के बारे में एक बिंदु जोड़ना चाहते हैं जिसका उल्लेख नहीं किया गया था। एक डेटाबेस में 200+ टेबल के साथ काम करना और नामकरण सम्मेलनों का मिश्रण होना। क्वेरी परिणामों के साथ इंटरैक्ट करने वाले कोड की समीक्षा करते समय, SELECT *डेवलपर्स को प्रभावित या उपलब्ध स्तंभों को निर्धारित करने के लिए शामिल तालिका स्कीमा (ओं) को देखने के लिए मजबूर करता है, जैसे कि foreachया serialize। बार-बार स्कीमा को देखने के लिए कि क्या हो रहा है, को देखने का काम अनिवार्य रूप से दोनों डिबगिंग और संबंधित कोड विकसित करने में शामिल कुल समय में वृद्धि करेगा।
3

91

चयनात्मक कथन में तारांकन वर्ण, "*", क्वेरी में शामिल तालिका के सभी स्तंभों के लिए आशुलिपि है।

प्रदर्शन

*आशुलिपि हो सकता है धीमी है क्योंकि:

  • सभी क्षेत्रों को अनुक्रमित नहीं किया जाता है, एक पूर्ण तालिका स्कैन को मजबूर करते हुए - कम कुशल
  • आप SELECT *तार पर भेजने के लिए क्या बचाते हैं, एक पूर्ण टेबल स्कैन का जोखिम उठाता है
  • जरूरत से ज्यादा डेटा लौटाना
  • चर लंबाई डेटा प्रकार का उपयोग करके पीछे आने वाले स्तंभों को खोज ओवरहेड में परिणामित किया जा सकता है

रखरखाव

उपयोग करते समय SELECT *:

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

डिज़ाइन

SELECT *एक विरोधी पैटर्न है :

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

जब "का चयन करें" का इस्तेमाल किया जाना चाहिए?

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

अन्यथा, स्पष्ट रूप से क्वेरी में उपयोग किए जाने वाले प्रत्येक स्तंभ को सूचीबद्ध करें - अधिमानतः तालिका उपनाम का उपयोग करते हुए।


20

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

यदि आप चाहते थे कि एक नया कॉलम जोड़ा जाए तो क्या इसका मतलब कम कोड को बदलना नहीं होगा?

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


21
खासकर अगर वह नया कॉलम तीन-मेगाबाइट BLOB है
मैटी विर्ककुनेन

2
@ माटी - लेकिन उम्मीद है कि वे "मेज पर एक विशाल BLOB स्तंभ को बंद करने देता है" की तुलना में अधिक विचार में डाल देंगे ! (हाँ एक मूर्ख आशा है कि मैं जानता हूँ, लेकिन एक आदमी सपना नहीं कर सकता?)
ChaosPandion

5
प्रदर्शन एक पहलू है, लेकिन अक्सर एक शुद्धता का पहलू भी होता है: परिणाम के आकार के साथ *अप्रत्याशित रूप से परिवर्तन हो सकता है और यह आवेदन में ही कहर बरपा सकता है: अध्यादेश द्वारा संदर्भित कॉलम (उदाहरण के लिए। sqldatareader.getring (2)) अचानक पुनः प्राप्त। एक अलग कॉलम, कोई भी INSERT ... SELECT *टूट जाएगा इत्यादि।
रेमस रुसानु

2
@ कोच: टेबल्स पर ब्लब्स लगाना वास्तव में आपके प्रदर्शन को बहुत नुकसान पहुंचाने वाला नहीं है ... जब तक आप सेलेक्ट * ... ;-) का उपयोग नहीं करते हैं
डेव मार्कल

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

4

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


"इस प्रकार संख्यात्मक सूचकांक द्वारा सुरक्षित रूप से संदर्भित किया जा सकता है" लेकिन जो कभी भी नाम के बजाय संख्यात्मक सूचकांक द्वारा एक स्तंभ को आजमाने और संदर्भित करने के लिए पर्याप्त बेवकूफ होगा !? यह एक दृश्य में चयन * का उपयोग करने की तुलना में बहुत बदतर विरोधी पैटर्न है।
MGOwen

@MGOwen: का उपयोग करते हुए select *और उसके बाद सूचकांक द्वारा स्तंभों का उपयोग भयानक होगा, लेकिन का उपयोग कर select X, Y, Zया select A,B,Cऔर उसके बाद जो कॉलम 0, 1 में डेटा के साथ कुछ करने के लिए उम्मीद कोड के लिए परिणामी डेटा पाठक गुजर, और 2 के लिए एक पूरी तरह से उचित तरीका प्रतीत होता है X, Y, Z या A, B, C दोनों पर कार्य करने के लिए समान कोड की अनुमति दें। ध्यान दें कि कॉलम के सूचकांक डेटाबेस में उनके आदेश के बजाय, SELECT स्टेटमेंट के भीतर उनके स्थान पर निर्भर करेंगे।
सुपरकैट

3

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


1
तो कॉलम का नामकरण कैसे मदद करता है? SQL सर्वर में, मौजूदा क्वेरीज़, कोड या SPs में एम्बेड की गई हैं, जब तक कि वे आपके नाम से नहीं चलती हैं, भले ही आपने कॉलम का नाम दिया हो। जब आप उनका परीक्षण करेंगे तो नए लोग असफल हो जाएंगे, लेकिन टेबल परिवर्तन से प्रभावित एसपी की तलाश में आपको काफी समय देना होगा। आप किस प्रकार की स्थितियों का उल्लेख कर रहे हैं जो डिजाइन समय पर पकड़ी जाएंगी?
क्रिस सिप

3

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

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


3

इसे ऐप और डेटाबेस के बीच युग्मन को कम करने के रूप में सोचें।

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


3

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

परिणाम की प्रत्येक पंक्ति में आप कितना डेटा प्राप्त कर सकते हैं, इसकी एक सीमा है। यदि आप अपनी तालिकाओं में फ़ील्ड जोड़ते हैं ताकि परिणाम उस सीमा से अधिक हो, तो आपको क्वेरी चलाने का प्रयास करते समय एक त्रुटि संदेश मिलता है।

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

यदि आप निर्दिष्ट करते हैं कि आप परिणाम में कौन से फ़ील्ड चाहते हैं, तो आप इस तरह के ओवरहेड ओवरफ़्लो से सुरक्षित हैं।



2

इस लेख से लिया गया संदर्भ।

"SELECT *" के साथ कभी न जाएं,

मुझे "Select *" का उपयोग करने का केवल एक कारण मिला है

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


1

आम तौर पर आपको SELECT * ...विभिन्न प्रकार के डेटा संरचनाओं में अपने परिणामों को फिट करना होगा । यह निर्दिष्ट किए बिना कि परिणाम किस क्रम में आ रहे हैं, यह सब कुछ ठीक से लाइन करने के लिए मुश्किल हो सकता है (और अधिक अस्पष्ट क्षेत्रों को याद करना बहुत आसान है)।

इस तरह से आप अपने टेबल पर (यहां तक ​​कि बीच में भी) उन सभी कारणों के लिए आवेदन में एसक्यूएल एक्सेस कोड को तोड़ने के बिना विभिन्न कारणों से जोड़ सकते हैं।


1

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

हालाँकि, इसके अलावा, यह देखना आसान है कि क्वेरी को देखते हुए कि कॉलम को क्या लोड किया जा रहा है, बिना यह देखने के लिए कि तालिका में क्या है।

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

यह भी इसी तरह का तर्क है कि यदि आप ऐसा कर रहे हैं तो आपको INSERTहमेशा कॉलम निर्दिष्ट करना चाहिए।


1

मुझे नहीं लगता कि वास्तव में इसके लिए कोई कंबल नियम हो सकता है। कई मामलों में, मैंने SELECT * से परहेज किया है, लेकिन मैंने डेटा फ्रेमवर्क के साथ भी काम किया है जहाँ SELECT * बहुत फायदेमंद था।

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


1

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

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


1

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

उदाहरण के लिए: BigQuery :

क्वेरी मूल्य निर्धारण

क्वेरी मूल्य निर्धारण आपके SQL कमांड और उपयोगकर्ता द्वारा परिभाषित कार्यों को चलाने की लागत को संदर्भित करता है। एक मीट्रिक का उपयोग करके प्रश्नों के लिए BigQuery शुल्क: संसाधित बाइट्स की संख्या।

और नियंत्रण प्रक्षेपण - चयन से बचें * :

सर्वोत्तम अभ्यास: नियंत्रण प्रक्षेपण - केवल उन कॉलमों की क्वेरी करें जिनकी आपको आवश्यकता है।

प्रोजेक्शन से तात्पर्य उन कॉलमों की संख्या से है जो आपकी क्वेरी द्वारा पढ़े जाते हैं। अतिरिक्त कॉलम प्रोजेक्ट करना अतिरिक्त (बर्बाद) I / O और भौतिककरण (लेखन परिणाम) को प्रभावित करता है।

डेटा को क्वेरी करने के लिए सेलेक्ट * का उपयोग करना सबसे महंगा तरीका है। जब आप SELECT * का उपयोग करते हैं, तो BigQuery तालिका में हर कॉलम का पूर्ण स्कैन करता है।


0

स्कीमा डिजाइन करने से पहले अपनी आवश्यकताओं को समझें (यदि संभव हो तो)।

डेटा के बारे में जानें, 1) अनुक्रमण 2) उपयोग किए गए भंडारण का प्रकार, 3) विक्रेता इंजन या सुविधाएँ; यानी ... कैशिंग, इन-मेमोरी क्षमता 4) डेटाटाइप्स 5) टेबल का आकार 6) क्वेरी की आवृत्ति 7) संबंधित वर्कलोड यदि संसाधन साझा किया गया है तो 8) टेस्ट

A) आवश्यकताएँ अलग-अलग होंगी। यदि हार्डवेयर अपेक्षित कार्यभार का समर्थन नहीं कर सकता है, तो आपको कार्य-भार में आवश्यकताओं को प्रदान करने के तरीके का पुनर्मूल्यांकन करना चाहिए। तालिका के अतिरिक्त स्तंभ के संबंध में। यदि डेटाबेस विचारों का समर्थन करता है, तो आप विशिष्ट नामांकित कॉलम (बनाम '' * ') के साथ विशिष्ट डेटा का एक अनुक्रमित (?) दृश्य बना सकते हैं। समय-समय पर अपने डेटा और स्कीमा की समीक्षा करें ताकि यह सुनिश्चित हो सके कि आप "कचरा-इन" -> "कचरा-बाहर" सिंड्रोम में कभी न चलें।

यह मानते हुए कि कोई अन्य समाधान नहीं है; आप निम्नलिखित को ध्यान में रख सकते हैं। किसी समस्या के हमेशा कई समाधान होते हैं।

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

2) भंडारण का प्रकार। Ie: यदि आप SSD's, डिस्क, या मेमोरी का उपयोग कर रहे हैं। I / O बार और सिस्टम / सीपीयू पर भार अलग-अलग होगा।

3) क्या DBA उच्च प्रदर्शन के लिए डेटाबेस / तालिकाओं को ट्यून कर सकता है? जो भी कारण के लिए मानते हुए, टीमों ने चयन का फैसला किया है '*' समस्या का सबसे अच्छा समाधान है; क्या DB या तालिका को मेमोरी में लोड किया जा सकता है। (या अन्य विधि ... शायद प्रतिक्रिया 2-3 सेकंड की देरी के साथ जवाब देने के लिए डिज़ाइन की गई थी? --- जबकि एक विज्ञापन कंपनी के राजस्व कमाने के लिए खेलता है।)

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

5) तालिका / डेटा का आकार। छोटे टेबल के साथ '*' का चयन आम है। वे आम तौर पर स्मृति में फिट होते हैं, और प्रतिक्रिया समय त्वरित होता है। फिर से .... अपनी आवश्यकताओं की समीक्षा करें। फ़ीचर रेंगने की योजना; हमेशा वर्तमान और संभव भविष्य की जरूरतों के लिए योजना बनाएं।

6) क्वेरी / प्रश्नों की आवृत्ति। सिस्टम पर अन्य कार्यभार से अवगत रहें। यदि यह क्वेरी हर सेकंड बंद हो जाती है, और तालिका छोटी है। परिणाम सेट को कैश / मेमोरी में बने रहने के लिए डिज़ाइन किया जा सकता है। हालाँकि, यदि क्वेरी डेटा के गीगाबाइट्स / टेराबाइट्स के साथ एक लगातार बैच प्रक्रिया है ... आप यह सुनिश्चित करने के लिए अतिरिक्त संसाधन समर्पित करने के लिए बेहतर हो सकते हैं कि अन्य कार्यभार प्रभावित न हों।

7) संबंधित कार्यभार। समझें कि संसाधनों का उपयोग कैसे किया जाता है। क्या नेटवर्क / सिस्टम / डेटाबेस / टेबल / एप्लिकेशन समर्पित है, या साझा किया गया है? हितधारक कौन हैं? क्या यह उत्पादन, विकास या QA के लिए है? क्या यह एक अस्थायी "त्वरित सुधार" है। क्या आपने परिदृश्य का परीक्षण किया है? आपको आश्चर्य होगा कि वर्तमान हार्डवेयर पर आज कितनी समस्याएं हो सकती हैं। (हां, प्रदर्शन तेज है ... लेकिन डिजाइन / प्रदर्शन अभी भी नीचा है।) क्या सिस्टम को प्रति सेकंड 10K प्रश्नों को प्रति सेकंड 5-10 प्रश्नों के प्रदर्शन की आवश्यकता है। डेटाबेस सर्वर समर्पित है, या अन्य अनुप्रयोगों को करते हैं, निगरानी साझा संसाधन पर निष्पादित करते हैं। कुछ एप्लिकेशन / भाषाएं; विभिन्न लक्षणों / समस्याओं के कारण O / S स्मृति की 100% खपत करेगा।

8) टेस्ट: अपने सिद्धांतों का परीक्षण करें, और जितना संभव हो उतना समझें। आपका चयन '*' समस्या एक बड़ी बात हो सकती है, या यह कुछ ऐसा हो सकता है जिसके बारे में आपको चिंता करने की आवश्यकता नहीं है।

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