क्या बूलियन फ़ील्ड को अनुक्रमित करने में कोई प्रदर्शन लाभ है?


103

मैं बस के बारे में एक प्रश्न है कि एक भी शामिल है लिखने के लिए कर रहा हूँ WHERE isok=1। जैसा कि नाम से पता चलता है, isokएक बूलियन फ़ील्ड है (वास्तव में एक TINYINT(1) UNSIGNEDकि जरूरत के रूप में 0 या 1 के लिए सेट है)।

क्या इस क्षेत्र को अनुक्रमित करने में कोई प्रदर्शन लाभ है? क्या इंजन (इस मामले में InnoDB) बेहतर या खराब होगा जो सूचकांक को देख रहा है?


जवाबों:


80

ज़रुरी नहीं। आपको एक किताब की तरह इसके बारे में सोचना चाहिए। यदि किसी पुस्तक में केवल 3 प्रकार के शब्द थे और आप उन सभी को अनुक्रमित करते हैं, तो आपके पास सामान्य पृष्ठों के समान ही अनुक्रमणिका पृष्ठ होंगे।

यदि एक मूल्य के अपेक्षाकृत कुछ रिकॉर्ड हैं, तो प्रदर्शन लाभ होगा। उदाहरण के लिए, यदि आपके पास 1000 रिकॉर्ड हैं और उनमें से 10 TRUE हैं, तो यदि आप खोज करते हैं तो यह उपयोगी होगाisok = 1

जैसा कि माइकल ड्यूरेंट ने उल्लेख किया है, यह भी धीमी गति से लिखता है।

संपादित करें: संभव दोहराव: अनुक्रमण बूलियन फ़ील्ड

यहाँ यह बताता है कि भले ही आपके पास एक इंडेक्स हो, अगर आपके पास बहुत सारे रिकॉर्ड हैं, तो यह इंडेक्स वैसे भी उपयोग नहीं करता है। MySQL इंडेक्स का उपयोग नहीं कर रहा है जब = 1 की जाँच कर रहा है, लेकिन इसका उपयोग = 0 के साथ कर रहा है


4
ऐसा लगता है कि "हाँ: 2 - नहीं: 1"। किसी के यहाँ गलत है, लेकिन कौन?
नीट द डार्क एबसोल

4
यह पूरी तरह से सही नहीं है, सूचकांक के बिना mySql को संबंधित पंक्तियों को खोजने के लिए पूरी तालिका को स्कैन करने की आवश्यकता है।
इलैंको

4
अन्यथा यह पूरे सूचकांक को स्कैन करेगा। (जो कि ज्यादातर मामलों में लंबे समय तक है)
माइकल कोपर

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

6
यह TRUE और FALSE के बीच समान वितरण को मानता है। जैसा कि नीचे @ouil द्वारा उल्लेख किया गया है, यदि आप एक बूलियन मूल्य की तलाश कर रहे हैं जो काफी दुर्लभ है, तो अभी भी कुछ समय लग सकता है। यह कहते हुए कि आपको हमेशा सूचकांक करना चाहिए, लेकिन मैं आपके डेटा की प्रकृति को मानूंगा और आपके प्रश्नों को अधिकांश डेटाबेस इंजनों के तहत भी मायने रखता है।
Mahemoff

118

बस यहाँ कई अन्य उत्तरों पर बारीक बिंदु रखने के लिए, मेरे अनुभव के बाद से, इस तरह के प्रश्नों को देखने वाले लोग एक ही नाव में थे जो हम थे, हम सभी ने सुना है कि बूलियन क्षेत्रों को अनुक्रमित करना व्यर्थ है, और अभी तक ...

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


हां, जबकि आपको निश्चित रूप से चीजों के 'क्यों' को समझने की कोशिश करनी चाहिए, हमेशा साथ में मापें और अपने वास्तविक डेटासेट पर विभिन्न चीजों को देखने की कोशिश करें कि क्या आपका सिद्धांत डीबी इंजन के वास्तविक व्यवहार के साथ मेल खाता है (आपको आश्चर्य होगा ... )
इलको

8
@Eelco आप सही हैं, लेकिन इस मामले में, परिणाम वास्तव में मूल सिद्धांत के साथ अच्छी तरह से मेल खाता है। मूल विचार कि यह नगण्य होना चाहिए केवल तभी समझ में आता है जब आप अपनी खोज से मेल खाने वाली वस्तुओं के लगभग 50% आने की संभावना रखते हैं। फिर, 100 मैचों को खोजने के लिए, डीबी को 200 वस्तुओं को पुनरावृत्त करना होगा। लेकिन अगर आइटम केवल 1% समय से मेल खाते हैं, तो उसे 10,000 वस्तुओं को पुनरावृत्त करना होगा।
Mahemoff

7
मुझे पसंद है जब लोग वास्तव में मैदान पर चीजों की कोशिश करते हैं और प्रदर्शन को केवल दार्शनिकता के बजाय प्रदर्शन लाभ देते हैं।
विक्टर जोरास

WHERE my_col > 0 इसके बजाय my_col = 1गति में मदद करने के लिए लगता है
हारून

28

यह वास्तविक प्रश्नों और सूचकांक / क्वेरी संयोजन की चयनात्मकता पर निर्भर करता है।

केस ए : हालत WHERE isok = 1और कुछ नहीं:

SELECT *
FROM tableX
WHERE isok = 1
  • यदि इंडेक्स चयनात्मक पर्याप्त है (कहते हैं कि आपके पास 1M पंक्तियाँ और केवल 1k है isok = 1), तो SQL इंजन संभवतः इंडेक्स का उपयोग करेगा और इसके बिना तेजी से होगा।

  • यदि अनुक्रमणिका पर्याप्त चयनात्मक नहीं है (जैसे कि आपके पास 1M पंक्तियाँ हैं और 100k से अधिक हैं isok = 1), तो SQL इंजन संभवतः अनुक्रमणिका का उपयोग नहीं करेगा और टेबल स्कैन करेगा।

केस बी : हालत WHERE isok = 1और अधिक सामान:

SELECT *
FROM tableX
WHERE isok = 1
  AND another_column = 17

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


मुझे लगता है, यह शीर्ष एक की तुलना में अधिक सही उत्तर है। डेटा का वितरण भी।
तान्या

12

यह डेटा के वितरण पर निर्भर करता है।

कल्पना कीजिए कि मेरे पास 1000 नज़दीकी टाइप पृष्ठों वाली एक किताब थी, और मेरी किताब के एकमात्र शब्द 'हाँ' और 'नहीं' बार-बार दोहराए गए और बेतरतीब ढंग से वितरित किए गए। अगर मुझे 'हां' के सभी उदाहरणों को गोल करने के लिए कहा जाता है, तो क्या किताब की मदद में एक सूचकांक होगा? निर्भर करता है।

यदि हां और ना का आधा-आधा यादृच्छिक वितरण होता है, तो सूचकांक में देखने से मदद नहीं मिलेगी। सूचकांक पुस्तक को बहुत बड़ा बना देगा, और वैसे भी मैं बस सामने से शुरू करने और प्रत्येक पृष्ठ पर 'हां' के सभी उदाहरणों की तलाश करने और उन्हें चक्कर लगाने के बजाय, प्रत्येक आइटम को देखने के बजाय जल्दी से काम करूंगा। इंडेक्स और फिर इंडेक्स प्रविष्टि से उस पेज के संदर्भ को ले रहा है जिसे वह संदर्भित करता है।

लेकिन अगर मेरे हज़ार पेज की किताब में 'हां' के सिर्फ दस उदाहरण हैं और बाकी सब सिर्फ लाखों नहीं हैं, तो एक सूचकांक मुझे 'हां' के उन दस उदाहरणों को खोजने और उन्हें चक्कर लगाने में समय की बचत करेगा ।

यह डेटाबेस में समान है। यदि यह 50:50 का वितरण है, तो एक सूचकांक मदद करने वाला नहीं है - डेटाबेस इंजन शुरू से अंत तक डेटा के माध्यम से जुताई से बेहतर है (पूर्ण टेबल स्कैन), और सूचकांक सिर्फ डेटाबेस को बड़ा करेगा, और लिखने और अद्यतन करने के लिए धीमा। लेकिन अगर यह 4000: 1 वितरण ( इस धागे में oucil के अनुसार ) की तरह कुछ है, तो एक इंडेक्स की तलाश इसे बेहद तेजी से बढ़ा सकती है, अगर यह 4000 में से 1 आइटम है जिसे आप ढूंढ रहे हैं।


5

नहीं, आमतौर पर नहीं।

आप आमतौर पर खोज के लिए फ़ील्ड्स को अनुक्रमित करते हैं जब उनके पास उच्च चयन / कार्डिनैलिटी होती है। ज्यादातर टेबल में बूलियन फील्ड की कार्डिनैलिटी बहुत कम होती है। यह आपके लेखन को आंशिक रूप से धीमा बना देगा।


3

दरअसल यह आपके द्वारा चलाए जा रहे प्रश्नों पर निर्भर करता है। लेकिन, आम तौर पर हाँ, साथ ही किसी अन्य प्रकार के क्षेत्र को अनुक्रमित करना।


2

हां एक सूचकांक प्रदर्शन में सुधार करेगा, सूचकांक के साथ और बिना EXPLAIN के आउटपुट की जांच करें।

डॉक्स से:

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

मुझे लगता है कि यह भी कहने के लिए एक सूचकांक नहीं होगा सुरक्षित है कमी इस मामले में प्रदर्शन, तो आप केवल इसे से लाभ के लिए है।


2
एक इंडेक्स हार्डडिस्क पर बहुत अधिक डेटा देता है और यह धीमा लिखता है ताकि आप केवल इससे लाभ न लें।
माइकल कोपर

1
सच है, लेकिन इस मामले में, एक TINYINT(1) UNSIGNEDकॉलम, डेटा का आकार छोटा होगा।
इलैंको

और अतिरिक्त लिखा ओवरहेड शायद बहुत कम है
इलको

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