MySQL में SELECT स्टेटमेंट के लिए रिकॉर्ड्स का डिफॉल्ट ऑर्डर क्या है?


66

मान लें कि आपके पास निम्न तालिका और डेटा है:

create table t (
    k int,
    v int,
    index k(k)
    ) engine=memory;

insert into t (k, v)
values (10, 1),
       (10, 2),
       (10, 3);

जब select * from t where k = 10कोई order byक्लॉज़ जारी नहीं किया जाता है, तो MySQL डिफ़ॉल्ट रूप से रिकॉर्ड को कैसे सॉर्ट करता है?

जवाबों:


75

SQL सर्वर के संबंध में एक समान प्रश्न के लिए मेरे उत्तर को फिर से लिखना :

SQL दुनिया में, ऑर्डर डेटा के एक सेट की एक अंतर्निहित संपत्ति नहीं है। इस प्रकार, आपको अपने RDBMS से कोई गारंटी नहीं मिलती है कि आपका डेटा एक निश्चित क्रम में वापस आ जाएगा - या यहां तक ​​कि एक सुसंगत क्रम में - जब तक आप अपने डेटा को ORDER BY खंड के साथ क्वेरी नहीं करते।

तो, आपके प्रश्न का उत्तर देने के लिए:

  • MySQL रिकॉर्ड्स को छाँटता है लेकिन यह बिना किसी निरंतरता के गारंटी के चाहता है।
  • यदि आप किसी भी चीज़ के लिए इस आदेश पर भरोसा करना चाहते हैं, तो आपको अपने वांछित आदेश का उपयोग करके निर्दिष्ट करना होगा ORDER BY। कुछ और करने के लिए खुद को अनचाहे आश्चर्य के लिए स्थापित करना है।

यह सभी SQL की संपत्ति है, न कि केवल MySQL की। SQL-92 युक्ति में प्रासंगिक पाठ है:

यदि एक खंड द्वारा आदेश> निर्दिष्ट नहीं है, तो क्यू की पंक्तियों का क्रम कार्यान्वयन-निर्भर है।

शाप देने वालों के लिए पाठ में इसी तरह के बिट्स हैं।


26

ORDER BYखंड की अनुपस्थिति में पंक्तियों का क्रम निम्न हो सकता है:

  • किसी भी दो भंडारण इंजन के बीच अलग;
  • यदि आप एक ही भंडारण इंजन का उपयोग करते हैं, तो यह एक ही भंडारण इंजन के किसी भी दो संस्करणों के बीच भिन्न हो सकता है; यहाँ उदाहरण के लिए, "आदेशों की क्रमबद्धता" तक स्क्रॉल करें।
  • यदि संग्रहण इंजन संस्करण समान है, लेकिन MySQL संस्करण भिन्न है, तो यह उन संस्करणों के बीच क्वेरी ऑप्टिमाइज़र परिवर्तनों के कारण भिन्न हो सकता है;
  • यदि सब कुछ समान है, तो यह चंद्रमा चरण के कारण भिन्न हो सकता है और यह ठीक है।

10

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

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


4

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

मैंने आपकी समान नमूना तालिका और डेटा लिया और 30 INSERTs चला और मुझे यह मिल गया:

mysql> use test
Database changed
mysql> drop table if exists t;
Query OK, 0 rows affected (0.00 sec)

mysql> create table t(k int, v int,index k(k)) engine=memory;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into t values
    -> (10, 1), (10, 2), (10, 3), (10, 1), (10, 2), (10, 3),
    -> (10, 1), (10, 2), (10, 3), (10, 1), (10, 2), (10, 3),
    -> (10, 1), (10, 2), (10, 3), (10, 1), (10, 2), (10, 3),
    -> (10, 1), (10, 2), (10, 3), (10, 1), (10, 2), (10, 3),
    -> (10, 1), (10, 2), (10, 3), (10, 1), (10, 2), (10, 3);
Query OK, 30 rows affected (0.00 sec)
Records: 30  Duplicates: 0  Warnings: 0

mysql> select * from t;
+------+------+
| k    | v    |
+------+------+
|   10 |    1 |
|   10 |    2 |
|   10 |    3 |
|   10 |    1 |
|   10 |    2 |
|   10 |    3 |
|   10 |    1 |
|   10 |    2 |
|   10 |    3 |
|   10 |    1 |
|   10 |    2 |
|   10 |    3 |
|   10 |    1 |
|   10 |    2 |
|   10 |    3 |
|   10 |    1 |
|   10 |    2 |
|   10 |    3 |
|   10 |    1 |
|   10 |    2 |
|   10 |    3 |
|   10 |    1 |
|   10 |    2 |
|   10 |    3 |
|   10 |    1 |
|   10 |    2 |
|   10 |    3 |
|   10 |    1 |
|   10 |    2 |
|   10 |    3 |
+------+------+
30 rows in set (0.00 sec)

mysql>

मैंने k: 10 और 11 के लिए दो अलग-अलग मानों को जोड़ने का परीक्षण करने का निर्णय लिया।

mysql> use test
Database changed
mysql> drop table if exists t;
Query OK, 0 rows affected (0.02 sec)

mysql> create table t(k int, v int,index k(k)) engine=memory;
Query OK, 0 rows affected (0.01 sec)

mysql> insert into t values
    -> (11, 1), (11, 2), (11, 3), (10, 1), (10, 2), (10, 3),
    -> (11, 1), (11, 2), (11, 3), (10, 1), (10, 2), (10, 3),
    -> (10, 1), (10, 2), (10, 3), (10, 1), (10, 2), (10, 3),
    -> (10, 1), (10, 2), (10, 3), (10, 1), (10, 2), (10, 3),
    -> (10, 1), (10, 2), (10, 3), (10, 1), (10, 2), (10, 3);
Query OK, 30 rows affected (0.00 sec)
Records: 30  Duplicates: 0  Warnings: 0

mysql> select * from t;
+------+------+
| k    | v    |
+------+------+
|   11 |    1 |
|   11 |    2 |
|   11 |    3 |
|   10 |    1 |
|   10 |    2 |
|   10 |    3 |
|   11 |    1 |
|   11 |    2 |
|   11 |    3 |
|   10 |    1 |
|   10 |    2 |
|   10 |    3 |
|   10 |    1 |
|   10 |    2 |
|   10 |    3 |
|   10 |    1 |
|   10 |    2 |
|   10 |    3 |
|   10 |    1 |
|   10 |    2 |
|   10 |    3 |
|   10 |    1 |
|   10 |    2 |
|   10 |    3 |
|   10 |    1 |
|   10 |    2 |
|   10 |    3 |
|   10 |    1 |
|   10 |    2 |
|   10 |    3 |
+------+------+
30 rows in set (0.00 sec)

mysql>

डालने का क्रम जैसा दिखता है। k = 11 पहली कुंजी हैशेड थी। 10. 11 के बजाय 10 पहले डालने के बारे में क्या? मेरे पास बस यही है:

mysql> use test
Database changed
mysql> drop table if exists t;
Query OK, 0 rows affected (0.02 sec)

mysql> create table t(k int, v int,index k(k)) engine=memory;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into t values
    -> (10, 1), (10, 2), (10, 3), (10, 1), (10, 2), (10, 3),
    -> (11, 1), (11, 2), (11, 3), (10, 1), (10, 2), (10, 3),
    -> (11, 1), (11, 2), (11, 3), (10, 1), (10, 2), (10, 3),
    -> (10, 1), (10, 2), (10, 3), (10, 1), (10, 2), (10, 3),
    -> (10, 1), (10, 2), (10, 3), (10, 1), (10, 2), (10, 3);
Query OK, 30 rows affected (0.00 sec)
Records: 30  Duplicates: 0  Warnings: 0

mysql> select * from t;
+------+------+
| k    | v    |
+------+------+
|   10 |    1 |
|   10 |    2 |
|   10 |    3 |
|   10 |    1 |
|   10 |    2 |
|   10 |    3 |
|   11 |    1 |
|   11 |    2 |
|   11 |    3 |
|   10 |    1 |
|   10 |    2 |
|   10 |    3 |
|   11 |    1 |
|   11 |    2 |
|   11 |    3 |
|   10 |    1 |
|   10 |    2 |
|   10 |    3 |
|   10 |    1 |
|   10 |    2 |
|   10 |    3 |
|   10 |    1 |
|   10 |    2 |
|   10 |    3 |
|   10 |    1 |
|   10 |    2 |
|   10 |    3 |
|   10 |    1 |
|   10 |    2 |
|   10 |    3 |
+------+------+
30 rows in set (0.00 sec)

mysql>

यह एकमत है !!! उत्तर का आदेश उत्तर है।

मेमोरी स्टोरेज इंजन के लिए अनुक्रमित का उपयोग करने पर सिडानोट्स

MEMORY की श्रेणी खोजों में तुलनात्मक रूप से भयावह प्रदर्शन होगा।

एक इंडेक्स बनाते समय, आप इंडेक्स USING BTREEकी परिभाषा के साथ क्लॉज को निर्दिष्ट कर सकते हैं । यह श्रेणी के प्रश्नों के लिए चीजों में सुधार करेगा।

किसी विशिष्ट पंक्ति के लिए सर्च कर रहे हैं या तो साथ प्रदर्शन में समान ही परिणाम मिलेगा HASHया BTREE

UPDATE 2011-09-22 11:18 EDT

मैंने आज कुछ दिलचस्प सीखा। मैंने पेरकोना से @Laurynas Biveinis द्वारा दिए गए लिंक को पढ़ा : Percona लिंक MySQL 5.5.15 के लिए मेमोरी टेबल के बारे में कुछ कहता है :

पंक्तियों का आदेश

ORDER BY की अनुपस्थिति में, पिछले मेमोरी कार्यान्वयन की तुलना में रिकॉर्ड को एक अलग क्रम में वापस किया जा सकता है। यह एक बग नहीं है। किसी भी आदेश के बिना विशिष्ट आदेश पर निर्भर कोई भी आवेदन अप्रत्याशित परिणाम दे सकता है। ORDER BY के बिना एक विशिष्ट ऑर्डर एक स्टोरेज इंजन और क्वेरी ऑप्टिमाइज़र कार्यान्वयन का एक साइड इफेक्ट है जो मामूली MySQL रिलीज के बीच बदल सकता है और हो सकता है।

आज देखने के लिए मेरे लिए यह एक अच्छी कड़ी थी। मैंने जो उत्तर दिया, उसने प्रदर्शित किया कि मैंने जिस तालिका को लोड किया था उसे MySQL 5.5.12 में TODAY की उम्मीद थी। जैसा कि पेरकोना और @ लौरिनस बिविनिस ने बताया है , एक और मामूली रिलीज में कोई गारंटी नहीं है।

इसलिए, अपने उत्तर की रक्षा करने की कोशिश करने के बजाय, मैं @Laurynas Biveinis के उत्तर को बढ़ावा देना चाहूंगा क्योंकि यह सबसे वर्तमान जानकारी है। Kudos और @Laurynas Biveinis के लिए नफरत करता है । मैं प्रश्नों के संस्करण-विशिष्ट उत्तरों को बढ़ावा नहीं देने के लिए विनम्रतापूर्वक @eevar को धन्यवाद देना चाहता हूं । वे दोनों आज मेरे अपोजिट हैं।

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