मैं निम्नलिखित MySQL तालिका (सरलीकृत) है:MySQL में इस अनुक्रमणिका को हटाने से मेरी क्वेरी 100x तेज हो जाती है?
CREATE TABLE `track` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(256) NOT NULL,
`is_active` tinyint(1) NOT NULL,
PRIMARY KEY (`id`),
KEY `is_active` (`is_active`, `id`)
) ENGINE=MyISAM AUTO_INCREMENT=7495088 DEFAULT CHARSET=utf8
'is_active' कॉलम पंक्तियों को मैं सबसे में अनदेखा करना चाहते निशान, लेकिन सभी नहीं, मेरे प्रश्नों की। मेरे पास कुछ प्रश्न हैं जो समय-समय पर इस तालिका से बाहर निकलते हैं। उनमें से एक इस तरह दिखता है:
SELECT id,title from track where (track.is_active=1 and track.id > 5580702) ORDER BY id ASC LIMIT 10;
यह क्वेरी निष्पादित करने में एक मिनट से अधिक समय लेती है। यहाँ कार्य योजना लागू है:
> EXPLAIN SELECT id,title from track where (track.is_active=1 and track.id > 5580702) ORDER BY id ASC LIMIT 10;
+----+-------------+-------+------+----------------+--------+---------+-------+---------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+----------------+--------+---------+-------+---------+-------------+
| 1 | SIMPLE | t | ref | PRIMARY,is_active | is_active | 1 | const | 3747543 | Using where |
+----+-------------+-------+------+----------------+--------+---------+-------+---------+-------------+
अब, अगर मैं MySQL बता 'is_active' सूचकांक अनदेखी करने के लिए, क्वेरी तत्क्षण होता है।
> EXPLAIN SELECT id,title from track IGNORE INDEX(is_active) WHERE (track.is_active=1 AND track.id > 5580702) ORDER BY id ASC LIMIT 10;
+----+-------------+-------+-------+---------------+---------+---------+------+---------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+---------+---------+------+---------+-------------+
| 1 | SIMPLE | t | range | PRIMARY | PRIMARY | 4 | NULL | 1597518 | Using where |
+----+-------------+-------+-------+---------------+---------+---------+------+---------+-------------+
अब, क्या वास्तव में अजीब बात है कि अगर मैं बल MySQL 'is_active' सूचकांक का उपयोग करने, क्वेरी एक बार फिर से तत्क्षण होता है!
+----+-------------+-------+-------+---------------+---------+---------+------+---------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+---------+---------+------+---------+-------------+
| 1 | SIMPLE | t | range | is_active |is_active| 5 | NULL | 1866730 | Using where |
+----+-------------+-------+-------+---------------+---------+---------+------+---------+-------------+
मैं सिर्फ इस व्यवहार समझ में नहीं आता। 'Is_active' इंडेक्स में, पंक्तियों को is_active द्वारा क्रमबद्ध किया जाना चाहिए, आईडी के बाद। मैं अपनी क्वेरी में 'is_active' और 'id' कॉलम दोनों का उपयोग करता हूं, इसलिए ऐसा लगता है कि आईडी को खोजने के लिए केवल पेड़ के चारों ओर कुछ हॉप करने की आवश्यकता है, फिर तालिका से शीर्षक प्राप्त करने के लिए उन आईडी का उपयोग करें।
क्या चल रहा है?
संपादित करें: अधिक जानकारी मैं क्या कर रहा हूँ पर:
- क्वेरी कैश विकलांग
- रनिंग अनुकूलन टेबल है और विश्लेषण तालिका कोई प्रभाव नहीं
- 6.620.372 पंक्तियों है 'is_active' सही पर सेट किया था। 874,714 पंक्तियों में गलत है 'is_active' सेट है।
- फोर्स INDEX (is_active) का उपयोग करके एक बार फिर क्वेरी को गति देता है।
- MySQL संस्करण 5.1.54
आप बेंचमार्किंग से पहले कैश साफ़ कर रहे हैं, है ना? – dfb
यह भी सुनिश्चित करें कि तालिका के आंकड़े चालू हैं और सूचकांक पुनर्निर्मित हैं। (हालांकि यह MySQL में किया गया है ;-) –
यदि आप WHERE शर्तों को उलट देते हैं तो क्या होता है? 'जहां (track.id> 5580702 और track.is_active = 1)' – EJP