2013-07-17 10 views
6

का उपयोग नहीं कर रहा है मेरी mySQL तालिका को सॉर्ट करना इंडेक्स का उपयोग नहीं करता है और मुझे नहीं पता कि क्यों।बहुत सरल mysql क्वेरी इंडेक्स

मुझे मिल गया है:

CREATE TABLE IF NOT EXISTS `test` (
    `a` int(11) NOT NULL, 
    `b` int(11) NOT NULL, 
    KEY `kk` (`a`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8; 

और इस:

id select_type table type possible_keys key key_len ref rows Extra 
1 SIMPLE  test ALL NULL   NULL NULL NULL 10009 Using filesort 
:

EXPLAIN SELECT * 
FROM test 
ORDER BY a 
रूप में अच्छी तरह इस

EXPLAIN SELECT * 
FROM test 
USE INDEX (kk) 
ORDER BY a 

रूप

मुझे इस देता है

मैं इस फाइल को नहीं देखना चाहता, और मेरी तालिका को सॉर्ट करने के लिए कुंजी केके का उपयोग करना चाहता हूं। मैं क्या गलत कर रहा हूं?


आपके पोस्ट लोगों के लिए धन्यवाद, वे मेरे प्रश्न का उत्तर देते हैं! हालांकि, अब मैं "टेबल स्कैन" और "फाइलोर्ट" द्वारा क्या मतलब है undestand नहीं है? यहां तक ​​कि यदि मैं सभी फ़ील्ड और तालिका की सभी पंक्तियों का चयन कर रहा हूं, तो उस कॉलम के सूचकांक के आंतरिक पेड़ (और) तालिका में देखकर एक तालिका द्वारा उस तालिका को सॉर्ट करना तेज़ नहीं है (और फिर तालिका में देखकर) प्रत्येक पंक्ति के लिए O (1) में अनुरोध किए गए अतिरिक्त कॉलम को दर्ज करें => इंडेक्स फ़ाइल तालिका फ़ाइल में प्रत्येक पंक्ति की भौतिक स्थिति को स्टोर करती है, या?), उदाहरण के अनुसार इंडेक्स को छूए बिना, तालिका फ़ाइल में (संभावित रूप से) यादृच्छिक रूप से संग्रहीत पंक्तियों में त्वरित रूप से ओ (एन * लॉग एन) में? मुझे लगता है कि मेरी एसक्यूएल में इंडेक्स कैसे काम करता है मेरी समझ गलत है। यह पूर्ण स्कैन का उपयोग करने के अधिक कुशल होने का अनुमान mysql -

उत्तर

11
  1. आप सभी पंक्तियों
  2. आप क्या मैं ऊपर कहा के बाद सभी स्तंभों

चयन किए जाने वाले का चयन कर रहे हैं।

यह सूचकांक का उपयोग कर पाने के लिए आपको लगता है कि यह पंक्तियों की उचित संख्या में सीमित हो जाएगी कुछ WHERE जोड़ने की जरूरत लौटे (जैसे कि 50)

+0

आप "सभी पंक्तियों" 1 में), सही मतलब है? –

+0

@a_horse_with_no_name: शायद मैं "पूरी तालिका" (या "सभी पंक्तियां" वास्तव में) का मतलब था। यह सुनिश्चित नहीं है कि यह अंग्रेजी में सही तरीके से कैसे व्यक्त किया जाए। – zerkms

+1

हां, "पूरी तालिका" या "सभी पंक्तियां" मुझे बेहतर लगेगी। –

0

के बाद आपके पास कोई कहां खंड यह एक filesort (तालिका स्कैन) करना होगा जब तक कि केवल आपके द्वारा चुने गए आइटम इंडेक्स से हैं। यह क्वेरी इंडेक्स का उपयोग करेगी। यदि आप एक स्तंभ सूचकांक में नहीं चुने गए (* या ख) यह एक फ़ाइल स्कैन करना होगा इस SQL Fiddle

EXPLAIN SELECT a FROM test ORDER BY a 

देखें हालांकि। या तो एक कवर इंडेक्स के साथ एक खंड जोड़ें या आपके द्वारा चुने गए कॉलम को बदलें।

2

@zerkms सही है, तालिका में सभी पंक्तियों को पढ़कर, MySQL निर्णय लेता है कि इसे तालिका के अधिकांश भाग को पढ़ना होगा, इसलिए इंडेक्स को पढ़ने की कोई आवश्यकता नहीं है। यदि आप तालिका का सबसेट चुनते हैं तो ऑप्टिमाइज़र व्यवहार बदलता है।

उदाहरण के लिए, मैंने आपकी तरह एक टेबल बनाया है और इसे 16384 पंक्तियों से भर दिया है, जिसमें 0 और 1000000 के बीच यादृच्छिक पूर्णांक हैं। फिर मैंने तालिका के विभिन्न सबसेट्स के लिए EXPLAIN का प्रयास किया, तालिका का पहला 15%, फिर 17%, फिर 1 9%।

mysql> EXPLAIN SELECT * FROM test where a < 150000 ORDER BY a; 
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+ 
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra  | 
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+ 
| 1 | SIMPLE  | test | range | kk   | kk | 5  | NULL | 2272 | Using where | 
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+ 

mysql> EXPLAIN SELECT * FROM test where a < 170000 ORDER BY a; 
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+ 
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra  | 
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+ 
| 1 | SIMPLE  | test | range | kk   | kk | 5  | NULL | 2560 | Using where | 
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+ 

mysql> EXPLAIN SELECT * FROM test where a < 190000 ORDER BY a; 
+----+-------------+-------+------+---------------+------+---------+------+-------+-----------------------------+ 
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra      | 
+----+-------------+-------+------+---------------+------+---------+------+-------+-----------------------------+ 
| 1 | SIMPLE  | test | ALL | kk   | NULL | NULL | NULL | 16384 | Using where; Using filesort | 
+----+-------------+-------+------+---------------+------+---------+------+-------+-----------------------------+ 

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

mysql> ALTER TABLE test ADD KEY kk2 (a,b); 
mysql> EXPLAIN SELECT a,b FROM test ORDER BY a; 
+----+-------------+-------+-------+---------------+------+---------+------+-------+-------------+ 
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra  | 
+----+-------------+-------+-------+---------------+------+---------+------+-------+-------------+ 
| 1 | SIMPLE  | test | index | NULL   | kk2 | 10  | NULL | 16384 | Using index | 
+----+-------------+-------+-------+---------------+------+---------+------+-------+-------------+ 
संबंधित मुद्दे