2012-06-07 17 views
7
MySQL Server version: 5.0.95 
Tables All: InnoDB 

मुझे एक MySQL डीबी क्वेरी के साथ कोई समस्या है। असल में मुझे लगता है कि अगर मैं एक विशेष वर्कर (50) फ़ील्ड tag.name इंडेक्स करता हूं, तो मेरे प्रश्न फ़ील्ड को अनुक्रमणित करने से अधिक लंबा (x10) लेते हैं। मैं इस सवाल को तेज करने की कोशिश कर रहा हूं, हालांकि मेरे प्रयास काउंटर उत्पादक प्रतीत होते हैं।MySQL अनुक्रमणिका नीचे धीमा कर रहा है

WHERE `t`.`name` IN ('news','home') 

मुझे लगता है कि अगर मैं एक के बिना सीधे tag तालिका क्वेरी एक ही मानदंड का उपयोग कर में शामिल होने पर ध्यान दिया है और नाम क्षेत्र अनुक्रमित के साथ, मेरे पास नहीं है:

अपराधी लाइन और क्षेत्र हो रहा है मुद्दा .. यह वास्तव में उम्मीद के रूप में तेजी से काम करता है।

उदाहरण क्वेरी **

 SELECT `a`.*, `u`.`pen_name` 
     FROM `tag_link` `tl` 
    INNER JOIN `tag` `t` 
      ON `t`.`tag_id` = `tl`.`tag_id` 
    INNER JOIN `article` `a` 
      ON `a`.`article_id` = `tl`.`link_id` 
    INNER JOIN `user` `u` 
      ON `a`.`user_id` = `u`.`user_id` 
     WHERE `t`.`name` IN ('news','home') 
     AND `tl`.`type` = 'article' 
     AND `a`.`featured` = 'featured' 
    GROUP BY `article_id` 
     LIMIT 0 , 5 

सूचकांक के साथ व्याख्या **

| id | select_type | table | type | possible_keys   | key  | key_len | ref    | rows | Extra              | 
+----+-------------+-------+--------+--------------------------+---------+---------+-------------------+------+-----------------------------------------------------------+ 
| 1 | SIMPLE  | t  | range | PRIMARY,name    | name | 152  | NULL    | 4 | Using where; Using index; Using temporary; Using filesort | 
| 1 | SIMPLE  | tl | ref | tag_id,link_id,link_id_2 | tag_id | 4  | portal.t.tag_id | 10 | Using where            | 
| 1 | SIMPLE  | a  | eq_ref | PRIMARY,fk_article_user1 | PRIMARY | 4  | portal.tl.link_id | 1 | Using where            | 
| 1 | SIMPLE  | u  | eq_ref | PRIMARY     | PRIMARY | 4  | portal.a.user_id | 1 |               | 
+----+-------------+-------+--------+--------------------------+---------+---------+-------------------+------+-----------------------------------------------------------+ 

सूचकांक बिना व्याख्या **

+----+-------------+-------+--------+--------------------------+---------+---------+---------------------+------+-------------+ 
| id | select_type | table | type | possible_keys   | key  | key_len | ref     | rows | Extra  | 
+----+-------------+-------+--------+--------------------------+---------+---------+---------------------+------+-------------+ 
| 1 | SIMPLE  | a  | index | PRIMARY,fk_article_user1 | PRIMARY | 4  | NULL    | 8742 | Using where | 
| 1 | SIMPLE  | u  | eq_ref | PRIMARY     | PRIMARY | 4  | portal.a.user_id | 1 |    | 
| 1 | SIMPLE  | tl | ref | tag_id,link_id,link_id_2 | link_id | 4  | portal.a.article_id | 3 | Using where | 
| 1 | SIMPLE  | t  | eq_ref | PRIMARY     | PRIMARY | 4  | portal.tl.tag_id | 1 | Using where | 
+----+-------------+-------+--------+--------------------------+---------+---------+---------------------+------+-------------+ 

टेबल बनाएं

CREATE TABLE `tag` (
    `tag_id` int(11) NOT NULL auto_increment, 
    `name` varchar(50) NOT NULL, 
    `type` enum('layout','image') NOT NULL, 
    `create_dttm` datetime default NULL, 
    PRIMARY KEY (`tag_id`) 
) ENGINE=InnoDB AUTO_INCREMENT=43077 DEFAULT CHARSET=utf8 

indexs

SHOW INDEX FROM tag_link; 
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | 
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 
| tag_link |   0 | PRIMARY |   1 | tag_link_id | A   |  42023 |  NULL | NULL |  | BTREE  |   | 
| tag_link |   1 | tag_id |   1 | tag_id  | A   |  10505 |  NULL | NULL |  | BTREE  |   | 
| tag_link |   1 | link_id |   1 | link_id  | A   |  14007 |  NULL | NULL |  | BTREE  |   | 
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 

SHOW INDEX FROM article; 
+---------+------------+------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 
| Table | Non_unique | Key_name   | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | 
+---------+------------+------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 
| article |   0 | PRIMARY   |   1 | article_id | A   |  5723 |  NULL | NULL |  | BTREE  |   | 
| article |   1 | fk_article_user1 |   1 | user_id  | A   |   1 |  NULL | NULL |  | BTREE  |   | 
| article |   1 | create_dttm  |   1 | create_dttm | A   |  5723 |  NULL | NULL | YES | BTREE  |   | 
+---------+------------+------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 

अंतिम समाधान ऐसा लगता है कि MySQL के सिर्फ डेटा को गलत तरीके से हल कर रहा है। अंत में यह टैग तालिका को देखने के लिए तेज़ी से निकला, एक आईडी को वापस करने वाली उप क्वेरी के रूप में।

+2

अन्य तालिकाओं पर अनुक्रमणिका क्या हैं? प्रत्येक इंडेक्स के लिए क्या कार्डिनिटी की सूचना दी जाती है? क्या आपने हाल ही में उनका विश्लेषण किया है? – symcbean

+0

sym के साथ सहमत हैं, कोशिश करें कि यह एनालॉग है कि ऐसा लगता है कि फाइलोर्ट – jcho360

+0

को गड़बड़ कर रहा है कृपया इस पृष्ठ पर एक नज़र डालें: http://www.mysqlperformanceblog.com/2009/03/05/what-does-using-filesort-mean -in-mysql/ – jcho360

उत्तर

1

आपकी टेबल कितनी बड़ी हैं? मैंने पहली बार बताया कि आपके पास "अस्थायी का उपयोग करना; फाइलों का उपयोग करना" खराब है। आपकी क्वेरी को डिस्क पर डंप किया जा रहा है जो इसे स्मृति प्रश्नों की तुलना में धीमा कर देता है। "चयन *" का उपयोग करने से बचने के लिए प्रयास करें और इसके बजाय आवश्यक न्यूनतम फ़ील्ड से पूछें।

+0

यह उदाहरण है, लेकिन टिप के लिए धन्यवाद। मुझे पता है कि फाइल सॉर्ट का उपयोग करना एक मुद्दा है लेकिन मुझे समझ में नहीं आता कि यह क्यों हो रहा है। जब मैं इंडेक्स जोड़ता हूं तो एक फाइलोर्ट का उपयोग किया जाता है .. इंडेक्स ड्रॉप करें और यह ठीक काम करता है .. – Lee

+0

मैं बस इस धागे में भाग गया: http://forums.mysql.com/read.php?115,73760,73760#msg- 73760 उनका सुझाव है कि आप अपने टैग.नाम के लिए लुकअप टेबल बनाएं ताकि आप अपने डेटा टेबल में पूर्णांक का उपयोग नामों से अलग कर सकें –

+0

इस तरह मैंने इस मुद्दे को हल किया .. टैग तालिका पर एक ही लुकअप करना तेज़ था एक उप प्रश्न के रूप में नाम। : डी .. जानकारी के लिए धन्यवाद। – Lee

3

ऐसा लगता है कि आलेख_आईडी आलेख तालिका के लिए प्राथमिक कुंजी है।

चूंकि आप article_id द्वारा समूहित कर रहे हैं, इसलिए GROS BY को करने के लिए MySQL को उस कॉलम द्वारा क्रम में रिकॉर्ड वापस करने की आवश्यकता है।

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

टैग.नाम पर इंडेक्स के साथ क्वेरी में, संपूर्ण लेख तालिका स्कैन करने की बजाय, यह सूचकांक का उपयोग करता है, लेकिन टैग तालिका के विरुद्ध, और वहां से शुरू होता है। दुर्भाग्यवश, ऐसा करने पर, ग्रुप बाय क्लॉज को पूरा करने के लिए रिकॉर्ड्स को बाद में article.article_id द्वारा सॉर्ट किया जाना चाहिए। पहली 5 पंक्तियों को प्राप्त करने के लिए, LIMIT ऑप्टिमाइज़ेशन लागू नहीं किया जा सकता है क्योंकि इसे पूरे परिणाम सेट को वापस करना होगा, फिर ऑर्डर करें।

इस मामले में, MySQL बस गलत तरीके से अनुमान लगाता है।

LIMIT क्लॉज के बिना, मुझे लगता है कि इंडेक्स का उपयोग करना तेज़ है, जो शायद MySQL अनुमान लगा रहा था।

संबंधित मुद्दे