2012-02-09 14 views
10

मेरे पास सामग्री की हजारों पंक्तियों (लगभग 3 मिलियन) के साथ एक जूमला टेबल है। मुझे टेबल क्वेरी पूछते समय जितनी जल्दी संभव हो सके डेटाबेस क्वेरी को पुनः लिखने में कुछ परेशानी हो रही है।कॉम्प्लेक्स माईएसQL क्वेरी अभी भी फाइलोर्ट का उपयोग कर रहा है हालांकि इंडेक्स मौजूद हैं

यहाँ मेरी पूरी क्वेरी है:

SELECT cc.title AS category, a.id, a.title, a.alias, a.title_alias, a.introtext, a.fulltext, a.sectionid, a.state, a.catid, a.created, a.created_by, a.created_by_alias, a.modified, a.modified_by, a.checked_out, a.checked_out_time, a.publish_up, a.publish_down, a.attribs, a.hits, a.images, a.urls, a.ordering, a.metakey, a.metadesc, a.access, CASE WHEN CHAR_LENGTH(a.alias) THEN CONCAT_WS(":", a.id, a.alias) ELSE a.id END AS slug, CASE WHEN CHAR_LENGTH(cc.alias) THEN CONCAT_WS(":", cc.id, cc.alias) ELSE cc.id END AS catslug, CHAR_LENGTH(a.`fulltext`) AS readmore, u.name AS author, u.usertype, g.name AS groups, u.email AS author_email 
FROM j15_content AS a 
LEFT JOIN j15_categories AS cc 
ON a.catid = cc.id 
LEFT JOIN j15_users AS u 
ON u.id = a.created_by 
LEFT JOIN j15_groups AS g 
ON a.access = g.id 
WHERE 1 
AND a.access <= 0 
AND a.catid = 108 
AND a.state = 1 
AND (publish_up = '0000-00-00 00:00:00' OR publish_up <= '2012-02-08 00:16:26') 
AND (publish_down = '0000-00-00 00:00:00' OR publish_down >= '2012-02-08 00:16:26') 
ORDER BY a.title, a.created DESC 
LIMIT 0, 10 

यहाँ से उत्पादन होता है एक व्याख्या:

+----+-------------+-------+--------+-------------------------------------------------------+-----------+---------+---------------------------+---------+-----------------------------+ 
| id | select_type | table | type | possible_keys           | key  | key_len | ref      | rows | Extra      | 
+----+-------------+-------+--------+-------------------------------------------------------+-----------+---------+---------------------------+---------+-----------------------------+ 
| 1 | SIMPLE  | a  | ref | idx_access,idx_state,idx_catid,idx_access_state_catid | idx_catid | 4  | const      | 3108187 | Using where; Using filesort | 
| 1 | SIMPLE  | cc | const | PRIMARY            | PRIMARY | 4  | const      |  1 |        | 
| 1 | SIMPLE  | u  | eq_ref | PRIMARY            | PRIMARY | 4  | database.a.created_by  |  1 |        | 
| 1 | SIMPLE  | g  | eq_ref | PRIMARY            | PRIMARY | 1  | database.a.access   |  1 |        | 
+----+-------------+-------+--------+-------------------------------------------------------+-----------+---------+---------------------------+---------+-----------------------------+ 

और दिखाने के लिए अनुक्रमित क्या मौजूद हैं, शो सूचकांक j15_content से:

+-------------+------------+------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 
| Table  | Non_unique | Key_name    | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | 
+-------------+------------+------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 
| j15_content |   0 | PRIMARY    |   1 | id   | A   |  3228356 |  NULL | NULL |  | BTREE  |   | 
| j15_content |   1 | idx_section   |   1 | sectionid | A   |   2 |  NULL | NULL |  | BTREE  |   | 
| j15_content |   1 | idx_access    |   1 | access  | A   |   1 |  NULL | NULL |  | BTREE  |   | 
| j15_content |   1 | idx_checkout   |   1 | checked_out | A   |   2 |  NULL | NULL |  | BTREE  |   | 
| j15_content |   1 | idx_state    |   1 | state  | A   |   2 |  NULL | NULL |  | BTREE  |   | 
| j15_content |   1 | idx_catid    |   1 | catid  | A   |   6 |  NULL | NULL |  | BTREE  |   | 
| j15_content |   1 | idx_createdby   |   1 | created_by | A   |   1 |  NULL | NULL |  | BTREE  |   | 
| j15_content |   1 | title     |   1 | title  | A   |  201772 |  4 | NULL |  | BTREE  |   | 
| j15_content |   1 | idx_access_state_catid |   1 | access  | A   |   1 |  NULL | NULL |  | BTREE  |   | 
| j15_content |   1 | idx_access_state_catid |   2 | state  | A   |   2 |  NULL | NULL |  | BTREE  |   | 
| j15_content |   1 | idx_access_state_catid |   3 | catid  | A   |   7 |  NULL | NULL |  | BTREE  |   | 
| j15_content |   1 | idx_title_created  |   1 | title  | A   |  3228356 |  8 | NULL |  | BTREE  |   | 
| j15_content |   1 | idx_title_created  |   2 | created  | A   |  3228356 |  NULL | NULL |  | BTREE  |   | 
+-------------+------------+------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 

जैसा कि आप देख सकते हैं कि डेटाबेस से डेटा के कुछ टुकड़े किए जा रहे हैं। अब मैंने क्वेरी को सरल बनाकर परीक्षण किया है कि असली मुद्दा ऑर्डर द्वारा ऑर्डर के साथ है। परिणाम आदेश देने के बिना, क्वेरी काफी संवेदनशील है, यहाँ एक स्पष्टीकरण है:

+----+-------------+-------+--------+-------------------------------------------------------+-----------+---------+---------------------------+---------+-------------+ 
| id | select_type | table | type | possible_keys           | key  | key_len | ref      | rows | Extra  | 
+----+-------------+-------+--------+-------------------------------------------------------+-----------+---------+---------------------------+---------+-------------+ 
| 1 | SIMPLE  | a  | ref | idx_access,idx_state,idx_catid,idx_access_state_catid | idx_catid | 4  | const      | 3108187 | Using where | 
| 1 | SIMPLE  | cc | const | PRIMARY            | PRIMARY | 4  | const      |  1 |    | 
| 1 | SIMPLE  | u  | eq_ref | PRIMARY            | PRIMARY | 4  | database.a.created_by  |  1 |    | 
| 1 | SIMPLE  | g  | eq_ref | PRIMARY            | PRIMARY | 1  | database.a.access   |  1 |    | 
+----+-------------+-------+--------+-------------------------------------------------------+-----------+---------+---------------------------+---------+-------------+ 

आप इसे घातक filesort कि सर्वर की मौत हो गई है देख सकते हैं। इस कई पंक्तियों के साथ, मैं इंडेक्स के माध्यम से सब कुछ अनुकूलित करने के लिए अपनी पूरी कोशिश कर रहा हूं लेकिन कुछ अभी भी इसके साथ सही नहीं है। कोई भी इनपुट बहुत प्रंशसनीय होगा।

कोई लाभ नहीं हुआ बल सूचकांक का उपयोग कर की कोशिश की:

explain  SELECT cc.title AS category, a.id, a.title, a.alias, a.title_alias, a.introtext, a.fulltext, a.sectionid, a.state, a.catid, a.created, a.created_by, a.created_by_alias, a.modified, a.modified_by, a.checked_out, a.checked_out_time, a.publish_up, a.publish_down, a.attribs, a.hits, a.images, a.urls, a.ordering, a.metakey, a.metadesc, a.access, CASE WHEN CHAR_LENGTH(a.alias) THEN CONCAT_WS(":", a.id, a.alias) ELSE a.id END AS slug, CASE WHEN CHAR_LENGTH(cc.alias) THEN CONCAT_WS(":", cc.id, cc.alias) ELSE cc.id END AS catslug, CHAR_LENGTH(a.`fulltext`) AS readmore, u.name AS author, u.usertype, g.name AS groups, u.email AS author_email 
    ->  FROM bak_content AS a 
    ->  FORCE INDEX (idx_title_created) 
    ->  LEFT JOIN bak_categories AS cc 
    ->  ON a.catid = cc.id 
    ->  LEFT JOIN bak_users AS u 
    ->  ON u.id = a.created_by 
    ->  LEFT JOIN bak_groups AS g 
    ->  ON a.access = g.id 
    ->  WHERE 1 
    ->  AND a.access <= 0 
    ->  AND a.catid = 108 
    ->  AND a.state = 1 
    ->  AND (publish_up = '0000-00-00 00:00:00' OR publish_up <= '2012-02-08 
    ->  AND (publish_down = '0000-00-00 00:00:00' OR publish_down >= '2012-0 
    ->  ORDER BY a.title, a.created DESC 
    ->  LIMIT 0, 10; 

का उत्पादन:

+----+-------------+-------+--------+---------------+---------+---------+------- 
| id | select_type | table | type | possible_keys | key  | key_len | ref 
+----+-------------+-------+--------+---------------+---------+---------+------- 
| 1 | SIMPLE  | a  | ALL | NULL   | NULL | NULL | NULL 
| 1 | SIMPLE  | cc | const | PRIMARY  | PRIMARY | 4  | const 
| 1 | SIMPLE  | u  | eq_ref | PRIMARY  | PRIMARY | 4  | database 
| 1 | SIMPLE  | g  | eq_ref | PRIMARY  | PRIMARY | 1  | database 
+----+-------------+-------+--------+---------------+---------+---------+------- 
+0

मैं इन इंडेक्स को एक कोशिश करूंगा: '(राज्य, कैटिड, एक्सेस)' या '(राज्य, कैटिड, publ_up)' या '(राज्य, कैटिड, publ_down)' –

+0

यदि आप 'LIMIT' का उपयोग नहीं करते हैं कई पंक्तियां वापस आती हैं? –

+0

आप 'idx_title_created' अनुक्रमणिका के उपयोग को मजबूर करने का भी प्रयास कर सकते हैं। –

उत्तर

0

कभी कभी MySQL मुसीबत उचित सूचकांक खोजने है। आप इसे उचित सूचकांक पर संकेत देकर हल कर सकते हैं।

सुझाव वाक्य रचना: http://dev.mysql.com/doc/refman/4.1/en/index-hints.html

करें कि आप सही सूचकांक और धुन प्रयोग करके यह प्रदर्शन है किया है।

चीयर्स!

+0

मैंने पहले ही इंडेक्स को मजबूर करने की कोशिश की है लेकिन इससे समस्या हल नहीं होती है। ऐसा लगता है कि संभवतः मैंने गलत कॉलम को अनुक्रमित किया है लेकिन मुझे यकीन नहीं है कि इंडेक्स में कौन से/होना चाहिए। मुझे लगता है कि क्वेरी की प्रकृति के कारण कुछ समग्र सूचकांक की आवश्यकता है। – user1199057

0

आप इस बदलाव की कोशिश कर सकते हैं:

SELECT cc.title AS category, ... 
FROM 
    (SELECT * 
     FROM j15_content AS a 
       USE INDEX (title)    --- with and without the hint 
     WHERE 1 
     AND a.access <= 0 
     AND a.catid = 108 
     AND a.state = 1 
     AND (publish_up = '0000-00-00 00:00:00' 
      OR publish_up <= '2012-02-08 00:16:26') 
     AND (publish_down = '0000-00-00 00:00:00' 
      OR publish_down >= '2012-02-08 00:16:26') 
     ORDER BY a.title, a.created DESC 
     LIMIT 0, 10 
    ) AS a 
    LEFT JOIN j15_categories AS cc 
    ON a.catid = cc.id 
    LEFT JOIN j15_users AS u 
    ON u.id = a.created_by 
    LEFT JOIN j15_groups AS g 
    ON a.access = g.id 

(catid, state, title) पर एक सूचकांक भी बेहतर मुझे लगता है कि होगा।

+0

धन्यवाद, मैं इसे जल्द ही कोशिश करूंगा और आपको वापस ले जाऊंगा। इंडेक्स का प्रभाव (शीर्षक, कैटिड, आईडी) (उस क्रम में) पर क्या प्रभाव होगा ताकि परिणाम पहले ही शीर्षक से क्रमबद्ध हो जाएं।मैं इसे 2 प्रश्नों में विभाजित करने के बारे में सोच रहा था, अगर मैं संभवतः केवल लेख आईडी खींच सकता हूं और फिर एक अलग क्वेरी कर सकता हूं जो तब आईडी से संबंधित सभी संबंधित जानकारी देता है जहां आईडी (1, 2, 3 इत्यादि) – user1199057

+0

क्वेरी अभी भी है इसके साथ वापस आता है: "# 1028 - दुर्भाग्य से निरस्त करें"। – user1199057

0

शायद यह मदद कर सकता है की कोशिश कर रहा:

CREATE INDEX idx_catid_title_created ON j15_content (catid,title(8),created); 
DROP INDEX idx_catid ON j15_content; 
5

AFAIK इस यथोचित एक सूचकांक, संकेत या स्वयं क्वेरी के पुनर्गठन का उपयोग कर हल नहीं किया जा सकता है।

कारण धीमा है यह तथ्य है कि इसे 2 एम पंक्तियों के एक फाइलॉर्ट की आवश्यकता होती है जो वास्तव में एक लंबा समय लेती है। यदि आप ऑर्डर पर ज़ूम इन करते हैं तो इसे ORDER BY a.title, a.created DESC के रूप में निर्दिष्ट किया गया है। समस्या 1 से अधिक कॉलम पर क्रमबद्ध करने और डीईएससी भाग रखने का संयोजन है। माइस्क्ल अवरोही अनुक्रमणिका का समर्थन नहीं करता है (कीवर्ड डीईएससी CREATE INDEX statement में समर्थित है लेकिन केवल भविष्य के उपयोग के लिए)।

सुझाया गया वर्कअराउंड एक अतिरिक्त कॉलम 'रिवर्स_क्रेटेड' बनाना है जो स्वचालित रूप से इस तरह से पॉप्युलेट हो जाता है कि आपकी क्वेरी ORDER BY a.title, a.reverse_created का उपयोग कर सकती है। तो आप इसे max_time - created_time से भरें।फिर उस संयोजन पर एक अनुक्रमणिका बनाएं और (यदि आवश्यक हो) उस सूचकांक को एक संकेत के रूप में निर्दिष्ट करें।

-Update- आप सक्षम होना चाहिए:

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

एक संक्षिप्त विवरण here नहीं है और यह भी उनमें से प्रत्येक के विस्तार के लिए लिंक:

0

आप बढ़ रही इन मूल्यों tmp_table_size और max_heap_table_size कोशिश की है।

आशा है कि इससे मदद मिलती है!

0

मुझे आशा है कि इस

SELECT 
    cc.title AS category, 
    a.id, a.title, a.alias, a.title_alias, 
    a.introtext, a.fulltext, a.sectionid, 
    a.state, a.catid, a.created, a.created_by, 
    a.created_by_alias, a.modified, a.modified_by, 
    a.checked_out, a.checked_out_time, 
    a.publish_up, a.publish_down, a.attribs, 
    a.hits, a.images, a.urls, a.ordering, a.metakey, 
    a.metadesc, a.access, 
    CASE WHEN CHAR_LENGTH(a.alias) THEN CONCAT_WS(":", a.id, a.alias) ELSE a.id END AS slug, 
    CASE WHEN CHAR_LENGTH(cc.alias) THEN CONCAT_WS(":", cc.id, cc.alias) ELSE cc.id END AS catslug, CHAR_LENGTH(a.`fulltext`) AS readmore, 
    u.name AS author, u.usertype, g.name AS groups, u.email AS author_email 
FROM 
(
    SELECT aa.* 
    FROM 
    (
     SELECT id FROM 
     FROM j15_content 
     WHERE catid=108 AND state=1 
     AND a.access <= 0 
     AND (publish_up = '0000-00-00 00:00:00' OR publish_up <= '2012-02-08 00:16:26') 
     AND (publish_down = '0000-00-00 00:00:00' OR publish_down >= '2012-02-08 00:16:26') 
     ORDER BY title,created DESC 
     LIMIT 0,10 
    ) needed_keys 
    LEFT JOIN j15_content aa USING (id) 
) a 
LEFT JOIN j15_categories AS cc ON a.catid = cc.id 
LEFT JOIN j15_users AS u ON a.created_by = u.id 
LEFT JOIN j15_groups AS g ON a.access = g.id; 

आप सबक्वेरी needed_keys

ALTER TABLE j15_content ADD INDEX subquery_ndx (catid,state,access,title,created); 

इसे आजमाइए के लिए एक समर्थन सूचकांक की आवश्यकता होगी वाक्य रचना सही है !!!

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