Mysql
 sql >> डेटाबेस >  >> RDS >> Mysql

एक MySQL डेटाबेस से रिकॉर्ड खींचने का कैननिकल तरीका क्या है जिसमें कम से कम/सबसे बड़ा फ़ील्ड है?

यह तरीका भी असामान्य नहीं है:

SELECT s1.*
FROM students s1
LEFT JOIN students s2 ON s1.rank < s2.rank
WHERE s2.uid IS NULL;

LEFT JOIN इस आधार पर काम करता है कि जब s1.rank अपने अधिकतम मान पर होता है, तो कोई s2.rank अधिक मान वाला नहीं होता है और s2 पंक्तियों का मान NULL होगा।

लेकिन मैं कहूंगा कि इसे करने का आपका तरीका सबसे सामान्य, समझने में आसान तरीका है, हां।

संपादित करें:इस सवाल पर कि यह कभी-कभी धीमा क्यों होता है:

इस क्वेरी का प्रदर्शन "इसे कितनी सावधानी से लिखा गया है" पर निर्भर करता है। उदाहरण के तौर पर अपना डेटा लिया:

drop table if exists students;
CREATE TABLE students
    (`uid` bigint, `last_name` varchar(5), `first_name` varchar(8), `dob` varchar(10), `email` varchar(16), `rank` int, `grade` int)
;

INSERT INTO students
    (`uid`, `last_name`, `first_name`, `dob`, `email`, `rank`, `grade`)
VALUES
    (13428700000001, 'Smith', 'John', '1990-12-03', '[email protected]', 99, 4),
    (13428721960000, 'Li', 'Kai Li', '1979-02-15', '[email protected]', 12, 2),
    (13428722180001, 'Zhang', 'Xi Xiong', '1993-11-09', '[email protected]', 5, 5),
    (13428739950000, 'Zhou', 'Ji Hai', '1991-06-06', '[email protected]', 234, 1),
    (13428739950001, 'Pan', 'Yao', '1992-05-12', '[email protected]', 43, 2),
    (13428740010001, 'Jin', 'Denny', '1994-06-02', '[email protected]', 198, 3),
    (13428740010002, 'Li', 'Fonzie', '1991-02-02', '[email protected]', 75, 3),
    (13428743370000, 'Ma', 'Haggar', '1991-08-16', '[email protected]', 47, 4),
    (13428743590001, 'Ren', 'Jenny', '1990-03-29', '[email protected]', 5, 2),
    (13428774040000, 'Chen', 'Dragon', '1999-04-12', '[email protected]', 23, 5),
    (13428774260001, 'Wang', 'Doctor', '1996-09-30', '[email protected]', 1, 5),
    (13430100000000, 'Chanz', 'Heyvery', '1994-04-04', '[email protected]', 107, 2)
;

आपकी क्वेरी की व्याख्या इस तरह दिखती है:

| ID | SELECT_TYPE |    TABLE | TYPE | POSSIBLE_KEYS |    KEY | KEY_LEN |    REF | ROWS |       EXTRA |
-------------------------------------------------------------------------------------------------------
|  1 |     PRIMARY | students |  ALL |        (null) | (null) |  (null) | (null) |   12 | Using where |
|  2 |    SUBQUERY | students |  ALL |        (null) | (null) |  (null) | (null) |   12 |             |

मेरी क्वेरी में से एक इस तरह:

| ID | SELECT_TYPE | TABLE | TYPE | POSSIBLE_KEYS |    KEY | KEY_LEN |    REF | ROWS |       EXTRA |
----------------------------------------------------------------------------------------------------
|  1 |      SIMPLE |    s1 |  ALL |        (null) | (null) |  (null) | (null) |   12 |             |
|  1 |      SIMPLE |    s2 |  ALL |        (null) | (null) |  (null) | (null) |   12 | Using where |

लगभग एक जैसा। कोई भी क्वेरी इंडेक्स का उपयोग नहीं करती है, सभी पंक्तियों को स्कैन किया जाता है। अब हम कॉलम rank . पर एक इंडेक्स जोड़ रहे हैं ।

drop table if exists students;
CREATE TABLE students
    (`uid` bigint, `last_name` varchar(5), `first_name` varchar(8), `dob` varchar(10), `email` varchar(16), `rank` int, `grade` int
    , key rankkey(rank)
    )
;

आपकी क्वेरी से स्पष्टीकरण:

| ID | SELECT_TYPE |    TABLE |   TYPE | POSSIBLE_KEYS |     KEY | KEY_LEN |    REF |   ROWS |                        EXTRA |
-----------------------------------------------------------------------------------------------------------------------------
|  1 |     PRIMARY | students |    ref |       rankkey | rankkey |       5 |  const |      1 |                  Using where |
|  2 |    SUBQUERY |   (null) | (null) |        (null) |  (null) |  (null) | (null) | (null) | Select tables optimized away |

बनाम मेरा:

| ID | SELECT_TYPE | TABLE | TYPE | POSSIBLE_KEYS |    KEY | KEY_LEN |    REF | ROWS |       EXTRA |
----------------------------------------------------------------------------------------------------
|  1 |      SIMPLE |    s1 |  ALL |        (null) | (null) |  (null) | (null) |   12 |             |
|  1 |      SIMPLE |    s2 |  ALL |       rankkey | (null) |  (null) | (null) |   12 | Using where |

आपकी क्वेरी इंडेक्स का उपयोग करती है, मेरा नहीं।

अब हम तालिका में एक प्राथमिक कुंजी जोड़ रहे हैं।

drop table if exists students;
CREATE TABLE students
    (`uid` bigint, `last_name` varchar(5), `first_name` varchar(8), `dob` varchar(10), `email` varchar(16), `rank` int, `grade` int
    , key rankkey(rank)
    , primary key(uid)
    );

अपनी क्वेरी से स्पष्ट करें:

| ID | SELECT_TYPE |    TABLE |   TYPE | POSSIBLE_KEYS |     KEY | KEY_LEN |    REF |   ROWS |                        EXTRA |
-----------------------------------------------------------------------------------------------------------------------------
|  1 |     PRIMARY | students |    ref |       rankkey | rankkey |       5 |  const |      1 |                  Using where |
|  2 |    SUBQUERY |   (null) | (null) |        (null) |  (null) |  (null) | (null) | (null) | Select tables optimized away |

और मेरी ओर से:

| ID | SELECT_TYPE | TABLE |  TYPE | POSSIBLE_KEYS |     KEY | KEY_LEN |    REF | ROWS |                                EXTRA |
-------------------------------------------------------------------------------------------------------------------------------
|  1 |      SIMPLE |    s1 |   ALL |        (null) |  (null) |  (null) | (null) |   12 |                                      |
|  1 |      SIMPLE |    s2 | index |       rankkey | rankkey |       5 | (null) |   12 | Using where; Using index; Not exists |

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

क्या होगा यदि प्रश्न लिखने वाला कोई गलती करता है? क्या होगा अगर वह इसे इस तरह लिखता है:

SELECT s1.*
FROM students s1
LEFT JOIN students s2 ON s1.rank < s2.rank
WHERE s2.last_name IS NULL;

क्वेरी अभी भी काम करती है और मान्य है, लेकिन

| ID | SELECT_TYPE | TABLE | TYPE | POSSIBLE_KEYS |    KEY | KEY_LEN |    REF | ROWS |       EXTRA |
----------------------------------------------------------------------------------------------------
|  1 |      SIMPLE |    s1 |  ALL |        (null) | (null) |  (null) | (null) |   12 |             |
|  1 |      SIMPLE |    s2 |  ALL |       rankkey | (null) |  (null) | (null) |   12 | Using where |

फिर से सूचकांक का उपयोग नहीं किया जाता है।

क्या होगा अगर हम प्राथमिक कुंजी को फिर से हटा दें और क्वेरी को इस तरह लिखें:

SELECT s1.*
FROM students s1
LEFT JOIN students s2 ON s1.rank < s2.rank
WHERE s2.rank IS NULL;

| ID | SELECT_TYPE | TABLE |  TYPE | POSSIBLE_KEYS |     KEY | KEY_LEN |    REF | ROWS |                    EXTRA |
-------------------------------------------------------------------------------------------------------------------
|  1 |      SIMPLE |    s1 |   ALL |        (null) |  (null) |  (null) | (null) |   12 |                          |
|  1 |      SIMPLE |    s2 | index |       rankkey | rankkey |       5 | (null) |   12 | Using where; Using index |

सूचकांक फिर से प्रयोग किया जाता है।

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

आशा है कि यह मदद करता है।




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL के साथ PHP के माध्यम से एक INSERT में दिनांक और समय टिकट कैसे जोड़ें?

  2. MySQL विदेशी कुंजी

  3. लारवेल वाक्पटु के साथ () -> अशक्त लौट रहा है

  4. MySQL नमूना डेटाबेस

  5. JSON को MySQL डेटाबेस कैसे निर्यात करें?