MySQL में आंतरिक रूप से FIELD () काम कैसे करता है


37

मैं समझता हूं कि ORDER BYक्लॉज कैसे काम करता है और FIELD()फ़ंक्शन कैसे काम करता है। मैं यह समझना चाहता हूं कि दोनों कैसे मिलकर काम करते हैं। पंक्तियों को कैसे पुनः प्राप्त किया जाता है और किस प्रकार क्रमबद्ध व्युत्पन्न किया जाता है

+----+---------+
| id |  name   |
+----+---------+
|  1 | stan    |
|  2 | kyle    |
|  3 | kenny   |
|  4 | cartman |
+----+---------+ 

SELECT * FROM mytable WHERE id IN (3,2,1,4) ORDER BY FIELD(id,3,2,1,4)

उपरोक्त क्वेरी में परिणाम होगा

+----+---------+
| id |  name   |
+----+---------+
|  3 | kenny   |
|  2 | kyle    |
|  1 | stan    |
|  4 | cartman |
+----+---------+ 

3, 2, 1, 4 द्वारा ORDER कहने के समान

प्रशन

  • यह आंतरिक रूप से कैसे काम करता है?
  • MySQL को पंक्तियाँ कैसे मिलती हैं, और क्रम क्रम की गणना कैसे करें?
  • MySQL को कैसे पता चलता है कि उसे id कॉलम द्वारा क्रमबद्ध करना है?

1
अपनी क्वेरी की इस भिन्नता को आज़माएं: SELECT *, FIELD(id,3,2,1,4) AS f FROM mytable WHERE id IN (3,2,1,4);फिर जोड़ें ORDER BY fया ORDER BY FIELD(id,3,2,1,4)पुनः प्रयास करें।
ypercube y

जवाबों:


64

रिकार्ड के लिए

SELECT * FROM mytable WHERE id IN (1,2,3,4) ORDER BY FIELD(id,3,2,1,4);

क्योंकि आप में सूची के आदेश की जरूरत नहीं है के रूप में अच्छी तरह से काम करना चाहिए WHEREखंड

यह कैसे काम करता है,

  • FIELD () एक फ़ंक्शन है जो कॉमा-सीमांकित सूची की अनुक्रमणिका स्थिति को लौटाता है यदि आप जिस मान को खोज रहे हैं वह मौजूद है।

    • यदि id = 1, तो FIELD (id, 3,2,1,4) 3 रिटर्न (स्थिति 1 जहां सूची में है)
    • IF id = 2, तो FIELD (id, 3,2,1,4) 2 रिटर्न (स्थिति 2 जहां सूची में है)
    • IF id = 3, तो FIELD (id, 3,2,1,4) 1 रिटर्न देता है (स्थिति जहां सूची में 3 है)
    • IF id = 4, तो FIELD (id, 3,2,1,4) 4 रिटर्न (स्थिति जहां 4 सूची में है)
    • यदि आईडी = कुछ और, तो FIELD (आईडी, 3,2,1,4) 0 रिटर्न (सूची में नहीं)
  • ORDER BYमूल्यों क्या द्वारा मूल्यांकन कर रहे हैं क्षेत्र () रिटर्न

आप सभी प्रकार के फैंसी ऑर्डर बना सकते हैं

उदाहरण के लिए, IF () फ़ंक्शन का उपयोग करना

SELECT * FROM mytable
WHERE id IN (1,2,3,4)
ORDER BY IF(FIELD(id,3,2,1,4)=0,1,0),FIELD(id,3,2,1,4);

इससे पहले 4 आईडी सूची में सबसे ऊपर दिखाई देंगे, अन्यथा, यह सबसे नीचे दिखाई देता है। क्यूं कर?

में ORDER BY, आप या तो 0 या 1 मिलता है।

  • यदि पहला कॉलम 0 है, तो पहले 4 आईडी में से कोई भी एक बनाएं
  • यदि पहला कॉलम 1 है, तो इसे बाद में प्रदर्शित करें

इसे पहले कॉलम में DESC के साथ फ्लिप करें

SELECT * FROM mytable
WHERE id IN (1,2,3,4)
ORDER BY IF(FIELD(id,3,2,1,4)=0,1,0) DESC,FIELD(id,3,2,1,4);

में ORDER BY, आप अभी भी 0 या 1 प्राप्त करते हैं।

  • यदि पहला कॉलम 1 है, तो कुछ भी बनाओ लेकिन पहले 4 आईडी दिखाई देते हैं।
  • यदि पहला कॉलम 0 है, तो मूल क्रम में पहले 4 आईडी बनाएं

आपका वास्तविक प्रश्न

यदि आप गंभीरता से इस पर इंटर्नल्स चाहते हैं, तो बुक के 189 और 192 के गोटो पेज

MySQL आंतरिक

एक वास्तविक गहरे गोता के लिए।

संक्षेप में, वहाँ एक C ++ वर्ग कहा जाता है ORDER *order( ORDER BYअभिव्यक्ति ट्री)। में JOIN::prepare, *orderनामक फ़ंक्शन में उपयोग किया जाता है setup_order()कक्षा के बीच में क्यों JOIN? हर क्वेरी, यहां तक ​​कि एक एकल तालिका के खिलाफ एक क्वेरी हमेशा एक JOIN के रूप में संसाधित होती है (मेरी पोस्ट देखें क्या JOIN स्थिति और WHERE की स्थिति के बीच निष्पादन अंतर है? )

इन सबके लिए सोर्स कोड है sql/sql_select.cc

जाहिर है, ORDER BYपेड़ का मूल्यांकन करने जा रहा है FIELD(id,3,2,1,4)। इस प्रकार, संख्या 0,1,2,3,4 वे मान हैं जिन्हें शामिल की गई पंक्ति के संदर्भ में ले जाते समय क्रमबद्ध किया जाता है।


1
यह एक उत्कृष्ट उत्कृष्ट व्याख्या है। इन विधियों का उपयोग करके मैं 3 ऑर्डर प्राप्त करने में सक्षम था, प्राथमिक प्राथमिक मूल्य जो सेट का अधिकतम है, फिर FIELD द्वारा, फिर FIELD सेट में नहीं लोगों के लिए एक और कॉलम द्वारा। कुछ मैंने कुछ समय पहले सपना नहीं देखा होगा। यह वास्तव में कैसे काम करता है यह समझाने के लिए समय निकालने के लिए धन्यवाद।
छिपकली

मान लीजिए कि Nदोनों में मूल्य हैं INऔर FIELD। इस उदाहरण में N=4। क्या मैं सही ढंग से समझता हूं कि यह क्वेरी कम से कम ~N^2संचालन करने वाली है। क्योंकि प्रत्येक FIELDगणना ~Nप्रत्येक पंक्ति के लिए एक बार तुलना करती है। यदि ऐसा है तो यह बड़े के लिए काफी धीमा है Nशायद यह बहुत अच्छा तरीका नहीं है?
घुमर

@Gherman FIELD()फ़ंक्शन एक O(1)ऑपरेशन होना चाहिए क्योंकि FIELD()एक संख्यात्मक सूचकांक है id। इसलिए मुझे कुछ और नहीं दिखता लेकिन O(n)पंक्तियों पर आधारित है। मुझे FIELD()ऐसा कोई पुनरावृत्ति ऑपरेशन नहीं दिखाई दे रहा है जैसे कि करने GREATEST()की आवश्यकता होगी।
रोलैंडमाइसीडीडीबीए

@RolandoMySQLDBA मेरी बात यह है कि यदि FIELDइसके Nसाथ तुलना करने के लिए तर्क हैं तो यह Nतुलना निष्पादित करेगा । Nयदि ऐसा न हो तो एक नंबर की तुलना दूसरे नंबरों से कैसे की जा सकती है O(N)? एकमात्र संभावना जिसके बारे में मैं सोच सकता हूं, वह हैश या तर्कों के वृक्ष जैसे विशेष डेटा संरचना के माध्यम से किसी प्रकार का अनुकूलन है। वास्तव में मुझे पता है कि INऐसा अनुकूलन है। मैं नहीं जानता FIELD। "संख्यात्मक सूचकांक" से आपका क्या तात्पर्य है?
घुमारवीं

1
अरे @ रेमंडजाइनल, CASE स्टेटमेंट ज्यादा समझ में आता है। इस केस के लिए, सिंटैक्टिक शुगर में सिर्फ राइटिंग है।
रोलैंडमाइसीडीडीबीए

1

हो सकता है कि यह वास्तविक कोड से बहुत दूर होगा ताकि आप जो चाहते हैं उससे कम स्तर न हो:

जब MySQL सॉर्ट किए गए क्रम में डेटा को पुनः प्राप्त करने के लिए इंडेक्स का उपयोग नहीं कर सकता है, तो यह सभी चयनित कॉलम और कुछ अतिरिक्त डेटा के साथ एक अस्थायी तालिका / परिणाम तैयार करता है - उनमें से एक प्रत्येक पंक्ति के लिए ORDER द्वारा अभिव्यक्ति मूल्य के परिणामों को संग्रहीत करने के लिए किसी प्रकार का कॉलम है - तब यह इस tmp तालिका को "filesort" रूटीन पर भेजता है जिसमें जानकारी होती है कि किस कॉलम को छांटना है। उसके बाद पंक्तियाँ क्रमबद्ध क्रम में होती हैं, इसलिए यह उन्हें एक-एक करके चुन सकती है और चयनित कॉलम लौटा सकती है।


यह स्पष्टीकरण इस बात पर ध्यान नहीं देता है कि FIELDगणना में कार्य कैसे किया जाता है। मुझे डर है कि यह प्रदर्शन पर एक महत्वपूर्ण प्रभाव डाल सकता है।
घुमारवीं

@Gherman मैं ऐसा नहीं सोचता, जब तक कि आप तर्कों की बहुत लंबी सूची का उपयोग नहीं कर रहे हैं (क्योंकि फ़ंक्शन तर्कों की संख्या के लिए रैखिक है । डेटा की पहुंच सरल तुलना की तुलना में परिमाण का एक क्रम है।
javavalik

हां, तर्कों की लंबी सूची। इस उदाहरण में जितने भी रिकॉर्ड हैं, उतने ही तर्क हैं।
घुमारवीं

मैं केवल सैकड़ों या हजारों का लेबल
लगाऊंगा

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