2012-12-13 37 views
15

द्वारा ORDER का उपयोग करता है, मैं MySQL संस्करण 5.0.95 के साथ ड्रूपल 6 का उपयोग कर रहा हूं और एक ऐसे बाधा पर जहां मेरे प्रश्नों में से एक जो हालिया आलेख दिनांक के आधार पर सामग्री प्रदर्शित करता है धीमा हो जाता है और इस्तेमाल होने की आवृत्ति पूरी तरह से साइट प्रदर्शन को मार देती है। पता चलता है नीचे परिणामMySQL क्वेरी को ऑप्टिमाइज़ करने में असमर्थ जो क्लॉज

 SELECT n.nid, 
      n.title, 
      ma.field_article_date_format_value, 
      ma.field_article_summary_value 
     FROM node n 
INNER JOIN content_type_article ma ON n.nid=ma.nid 
INNER JOIN term_node tn   ON n.nid=tn.nid 
     WHERE tn.tid= 153 
     AND n.status=1 
    ORDER BY ma.field_article_date_format_value DESC 
     LIMIT 0, 11; 

क्वेरी की व्याख्या: प्रश्न में प्रश्न के रूप में नीचे है

+----+-------------+-------+--------+--------------------------+---------+---------+----------------------+-------+---------------------------------+ 
| id | select_type | table | type | possible_keys   | key  | key_len | ref     | rows | Extra       | 
+----+-------------+-------+--------+--------------------------+---------+---------+----------------------+-------+---------------------------------+ 
| 1 | SIMPLE  | tn | ref | PRIMARY,nid    | PRIMARY | 4  | const    | 19006 | Using temporary; Using filesort | 
| 1 | SIMPLE  | ma | ref | nid,ix_article_date  | nid  | 4  | drupal_mm_stg.tn.nid |  1 |         | 
| 1 | SIMPLE  | n  | eq_ref | PRIMARY,node_status_type | PRIMARY | 4  | drupal_mm_stg.ma.nid |  1 | Using where      | 
+----+-------------+-------+--------+--------------------------+---------+---------+----------------------+-------+---------------------------------+ 

इस क्वेरी अपेक्षाकृत सरल लग रहा था और सीधे आगे और लेख जो एक वर्ग के पुन: प्राप्त करता (अवधि) 153 और स्थिति 1 (प्रकाशित) हैं। लेकिन स्पष्ट रूप से अस्थायी तालिका का उपयोग करना और फाइलॉर्ट का उपयोग करना मतलब है कि क्वेरी को इसके बारे में ब्राउज़ करने के बारे में सीखा है।

ORDER BY खंड से field_article_date_format_value को निकालने से अस्थायी उपयोग करना हल हो जाता है; फाइलॉर्ट का उपयोग करने से क्वेरी निष्पादन समय कम हो जाता है लेकिन इसकी आवश्यकता होती है और इसे बंद नहीं किया जा सकता है, दुर्भाग्यवश साइट प्रदर्शन के लिए समान रूप से समान है।

मेरा मुकाबला यह है कि अधिकांश समस्याएं टर्म_नोड तालिका से आती हैं जो लेखों के लिए लेखों को मानचित्र करती है और कई रिश्ते तालिका है जिसका अर्थ है कि आलेख एक्स 5 श्रेणियों सी 1 से जुड़ा हुआ है .... सी 5 में 5 प्रविष्टियां होंगी उस तालिका में, यह तालिका आउट-ऑफ-द-बॉक्स ड्रूपल से है।

भारी डीबी सामग्री के साथ काम मिलती-जुलती क्वेरी ( When ordering by date desc, "Using temporary" slows down query, MySQL performance optimization: order by datetime field) मैं content_type_article जिसका datetime क्षेत्र के साथ ORDER BY खंड में प्रयोग किया जाता है के लिए एक समग्र सूचकांक बनाने की कोशिश की के कुछ के माध्यम से कुछ मेरे लिए नए और जा रहा है इसमें एक और कुंजी (निड) के साथ और INDEX को मजबूर करने की कोशिश की।

SELECT n.nid, n.title, 
      ma.field_article_date_format_value, 
      ma.field_article_summary_value 
     FROM node n 
INNER JOIN content_type_article ma FORCE INDEX (ix_article_date) ON n.nid=ma.nid 
INNER JOIN term_node tn ON n.nid=tn.nid 
    WHERE tn.tid= 153 
     AND n.status=1 
    ORDER BY ma.field_article_date_format_value DESC 
    LIMIT 0, 11; 

परिणाम और निम्न क्वेरी व्याख्या नहीं मालूम था मदद करने के लिए बहुत

+----+-------------+-------+--------+--------------------------+-----------------+---------+----------------------+-------+---------------------------------+ 
| id | select_type | table | type | possible_keys   | key    | key_len | ref     | rows | Extra       | 
+----+-------------+-------+--------+--------------------------+-----------------+---------+----------------------+-------+---------------------------------+ 
| 1 | SIMPLE  | tn | ref | PRIMARY,nid    | PRIMARY   | 4  | const    | 18748 | Using temporary; Using filesort | 
| 1 | SIMPLE  | ma | ref | ix_article_date   | ix_article_date | 4  | drupal_mm_stg.tn.nid |  1 |         | 
| 1 | SIMPLE  | n  | eq_ref | PRIMARY,node_status_type | PRIMARY   | 4  | drupal_mm_stg.ma.nid |  1 | Using where      | 
+----+-------------+-------+--------+--------------------------+-----------------+---------+----------------------+-------+---------------------------------+ 

क्षेत्रों n.nid, ca.nid, ma.field_article_date_format_value सभी इंडेक्स किए गए। सीमा 0,11 के साथ डीबी पूछने से ऑर्डर द्वारा ऑर्डर के साथ लगभग 7-10 सेकंड लगते हैं लेकिन इसके बिना क्वेरी मुश्किल से एक सेकंड लेती है। डेटाबेस इंजन MyISAM है। इस पर किसी भी प्रकार की सहायताबहुत प्रशंसनीय होगी।

कोई भी उत्तर जो मुझे इस प्रश्न को सामान्य (जैसे तारीख के अनुसार बिना किसी प्रश्न के समान गति) में प्राप्त करने में मेरी सहायता कर सकता है, वह बहुत अच्छा होगा। nid और field_article_date_format_value के संयोजन के रूप में एक समग्र क्वेरी बनाने के मेरे प्रयास और क्वेरी में उपयोग ने कारण की सहायता नहीं की। मैं समस्या और किसी भी नए सुझाव पर अतिरिक्त जानकारी प्रदान करने के लिए खुला हूं।

उत्तर

2

MySQL आपकी क्वेरी को "अनुकूलित" कर रहा है ताकि यह पहले टर्म_नोड तालिका से चयन हो, भले ही आप पहले नोड से चयन करने के लिए निर्दिष्ट कर रहे हों। डेटा को नहीं जानते, मुझे यकीन नहीं है कि इष्टतम तरीका कौन सा है। Term_node तालिका निश्चित रूप से है जहां से आपके प्रदर्शन समस्याएं ~ 1 9, 000 रिकॉर्ड वहां से चुनी जा रही हैं।

आदेश के बिना सीमा लगभग हमेशा तेज होती है क्योंकि जैसे ही यह निर्दिष्ट सीमा पाता है, MySQL बंद हो जाता है। ऑर्डर द्वारा, इसे पहले सभी रिकॉर्ड्स ढूंढना होगा और उन्हें सॉर्ट करना होगा, फिर निर्दिष्ट सीमा प्राप्त करें।

कोशिश करने की सरल बात जॉइन क्लॉज में अपनी WHERE स्थिति को स्थानांतरित कर रही है, जहां यह होना चाहिए। वह फ़िल्टर तालिका में शामिल होने के लिए विशिष्ट है। यह सुनिश्चित करेगा कि MySQL इसे गलत तरीके से अनुकूलित नहीं करता है।

INNER JOIN term_node tn ON n.nid=tn.nid AND tn.tid=153 

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

SELECT ... 
FROM node n 
INNER JOIN content_type_article ma FORCE INDEX (ix_article_date) ON n.nid=ma.nid 
INNER JOIN (SELECT DISTINCT nid FROM term_node WHERE tid=153) tn ON n.nid=tn.nid 
WHERE n.status=1 
ORDER BY ma.field_article_date_format_value DESC 
LIMIT 0,11 

MySQL 5.0 में व्युत्पन्न तालिकाओं के साथ कुछ सीमाएं हैं, इसलिए यह काम नहीं कर सकता है। यद्यपि काम आसपास हैं।

+0

प्रतिक्रिया के लिए धन्यवाद, हालांकि शब्द_नोड एन है: एन किसी विशेष शब्द के परिणामस्वरूप नोड्स मेरे मामले में अलग होंगे .. मैंने पहले व्युत्पन्न तालिका दृष्टिकोण को आजमाया था लेकिन क्वेरी निष्पादन लगभग पारंपरिक साधनों जैसा ही था । – optimusprime619

4

Using temporary; Using filesort का मतलब है कि MySQL को अस्थायी परिणाम तालिका बनाने की आवश्यकता है और आपको आवश्यक परिणाम प्राप्त करने के लिए इसे सॉर्ट करना होगा। यह अक्सर ORDER BY ... DESC LIMIT 0,n निर्माण का परिणाम होता है जिसका उपयोग आप नवीनतम पोस्टिंग प्राप्त करने के लिए कर रहे हैं। अपने आप में विफलता का संकेत नहीं है। इसे देखें: http://www.mysqlperformanceblog.com/2009/03/05/what-does-using-filesort-mean-in-mysql/

कुछ कोशिश करने के लिए यहां कुछ चीज़ें दी गई हैं। मुझे पूरा यकीन नहीं है कि वे काम करेंगे; प्रयोग करने के लिए अपने डेटा के बिना जानना मुश्किल है।

क्या content_type_article.field_article_date_format_value पर कोई बीटीई इंडेक्स है? यदि ऐसा है, तो यह मदद कर सकता है।

क्या आपको 11 सबसे हाल के लेख प्रदर्शित करना है? या क्या आप पिछले सप्ताह या महीने में दिखाई देने वाले 11 सबसे हालिया लेख प्रदर्शित कर सकते हैं? यदि ऐसा है तो आप इस लाइन को अपने WHERE खंड में जोड़ सकते हैं। लेखों के मिलान के लिए समय की शुरुआत में सभी तरह से देखने के बजाय यह आपकी सामग्री को आज तक फ़िल्टर करेगा। यदि आपके पास लंबे समय से स्थापित ड्रूपल साइट है तो यह विशेष रूप से सहायक होगा।

AND ma.field_article_date_format_value >= (CURRENT_TIME() - INTERVAL 1 MONTH) 

सबसे पहले, INNER जॉइन ऑपरेशंस के आदेश को फ़्लिप करने का प्रयास करें। दूसरा, शामिल मानदंड में tid = 153 को शामिल करें। यह उस सारणी तालिका के आकार को कम कर सकता है जिसे आपको क्रमबद्ध करने की आवश्यकता है।

SELECT n.nid, 
      n.title, 
      ma.field_article_date_format_value, 
      ma.field_article_summary_value 
     FROM node n 
INNER JOIN term_node tn   ON (n.nid=tn.nid AND tn.tid = 153) 
INNER JOIN content_type_article ma ON n.nid=ma.nid 
    WHERE n.status=1 
     AND ma.field_article_date_format_value >= (CURRENT_TIME() - INTERVAL 1 MONTH) 
    ORDER BY ma.field_article_date_format_value DESC 
    LIMIT 0, 11; 

उन रहे हैं

+0

फीडबैक के लिए धन्यवाद, हाँ बीटीआई जगह पर है, मेरी चिंता यह है कि मैं किसी भी तरह से अस्थायी तालिका के उपयोग को अस्वीकार कर सकता हूं और इंडेक्सिंग के साथ सॉर्ट कर सकता हूं .. और व्यवसाय तर्क के लिए आवश्यक है कि हाल के लेख प्रदर्शित किए जाएं एक सप्ताह या महीने – optimusprime619

6

आपकी क्वेरी पर एक नज़र ले रहा है और स्पष्ट करते हैं, यह जहां खंड में n.status = 1 होने की तरह लगता है खोज बहुत कर रही है: सभी एक साथ मेरे सुझाव इस प्रकार हैं अक्षम क्योंकि आपको जॉइन द्वारा परिभाषित पूरे सेट को वापस करने की आवश्यकता है और फिर स्थिति = 1. लागू करें टर्म_नोड तालिका से जुड़ने का प्रयास करें जिसे तुरंत WHERE द्वारा फ़िल्टर किया गया है और फिर स्थिति स्थिति को तुरंत जोड़ना शामिल करें। इसे आज़माएं और कृपया मुझे बताएं कि यह कैसा चल रहा है।

SELECT n.nid, n.title, 
      ma.field_article_date_format_value, 
      ma.field_article_summary_value 
     FROM term_node tn 
INNER JOIN node n ON n.nid=tn.nid AND n.status=1 
INNER JOIN content_type_article ma FORCE INDEX (ix_article_date) ON n.nid=ma.nid 
    WHERE tn.tid= 153 
    ORDER BY ma.field_article_date_format_value DESC 
    LIMIT 0, 11; 
4

1) कवर अनुक्रमित

मुझे लगता है कि सरल जवाब है "को कवर अनुक्रमणिका" हो सकता है।

खासकर content_type_article तालिका पर। "कवरिंग इंडेक्स" में अग्रणी कॉलम के रूप में ORDER BY में अभिव्यक्ति है, और इसमें क्वेरी द्वारा संदर्भित सभी कॉलम शामिल हैं।यहाँ सूचकांक मैं बनाया (अपने परीक्षण मेज पर) है:

CREATE INDEX ct_article_ix9 
    ON content_type_article 
     (field_article_date_format_value, nid, field_article_summary_value); 

और यहाँ व्याख्या मैं क्वेरी से प्राप्त (के बाद मैं उदाहरण तालिका का निर्माण,, InnoDB इंजन का उपयोग कर प्रत्येक मेज पर एक कवर सूचकांक सहित का एक अंश है):

_type table type key    ref   Extra      
------ ----- ----- -------------- ----------- ------------------------ 
SIMPLE ma index ct_article_ix9 NULL   Using index 
SIMPLE n ref node_ix9   ma.nid  Using where; Using index 
SIMPLE tn ref term_node_ix9 n.nid,const Using where; Using index 

नोट नहीं 'Using filesort' योजना में दिखाया गया है, और योजना क्वेरी, जो मूल रूप से मतलब है कि क्वेरी के लिए आवश्यक डेटा के सभी इंडेक्स पृष्ठों से लिया गया है में संदर्भित हर तालिका के लिए 'Using index' पता चलता है कि , अंतर्निहित तालिका से किसी भी पेज को संदर्भित करने की आवश्यकता नहीं है। (आपका टेबल अपने परीक्षण तालिकाओं की तुलना में बहुत अधिक पंक्तियाँ है, लेकिन अगर आप एक योजना है कि इस तरह दिखता है समझाने प्राप्त कर सकते हैं, तो आप बेहतर प्रदर्शन प्राप्त कर सकते हैं।)


पूर्णता के लिए, यहाँ पूरी व्याख्या उत्पादन है:

+----+-------------+-------+-------+---------------+----------------+---------+---------------------+------+--------------------------+ 
| id | select_type | table | type | possible_keys | key   | key_len | ref     | rows | Extra     | 
+----+-------------+-------+-------+---------------+----------------+---------+-------- ------------+------+--------------------------+ 
| 1 | SIMPLE  | ma | index | NULL   | ct_article_ix9 | 27  | NULL    | 1 | Using index    | 
| 1 | SIMPLE  | n  | ref | node_ix9  | node_ix9  | 10  | testps.ma.nid,const | 11 | Using where; Using index | 
| 1 | SIMPLE  | tn | ref | term_node_ix9 | term_node_ix9 | 10  | testps.n.nid,const | 11 | Using where; Using index | 
+----+-------------+-------+-------+---------------+----------------+---------+---------------------+------+--------------------------+ 
3 rows in set (0.00 sec) 

मैं छोड़कर FORCE INDEX संकेत छोड़, आपकी क्वेरी के लिए कोई परिवर्तन नहीं किए। यहाँ अन्य दो "को कवर अनुक्रमणिका" है कि मैं क्वेरी में संदर्भित अन्य दो टेबल पर बनाई गई हैं:

CREATE INDEX node_ix9 
    ON node (`nid`,`status`,`title`); 

CREATE INDEX term_node_ix9 
    ON term_node (nid,tid); 

(ध्यान दें कि यदि nidnode मेज पर क्लस्टरिंग कुंजी है, तो आप को कवर सूचकांक की जरूरत नहीं हो सकता है नोड टेबल पर।)


2) जॉइन के स्थान पर सहसंबंधित सबक्वायरी का उपयोग करें?

यदि पिछले विचार में कुछ भी सुधार नहीं होता है, तो, एक और विकल्प के रूप में, मूल क्वेरी अधिकतम 11 पंक्तियों को वापस कर रही है, इसलिए आप शामिल संचालन से बचने के लिए क्वेरी को फिर से लिखने का प्रयास कर सकते हैं, और इसके बजाय सहसंबंध का उपयोग कर सकते हैं सबक्वेरी। नीचे दी गई क्वेरी की तरह कुछ।

ध्यान दें कि यह क्वेरी मूल क्वेरी से काफी भिन्न है। अंतर यह है कि इस क्वेरी के साथ, context_type_article तालिका से एक पंक्ति केवल एक बार लौटा दी जाएगी। जॉइन का उपयोग कर क्वेरी के साथ, उस तालिका से एक पंक्ति node और term_node तालिकाओं से कई पंक्तियों से मेल खाई जा सकती है, जो एक ही पंक्ति को एक से अधिक बार वापस कर देगी। इसे या तो वांछनीय या अवांछनीय के रूप में देखा जा सकता है, यह वास्तव में कार्डिनिटी पर निर्भर करता है, और क्या परिणाम विनिर्देश को पूरा करता है।

SELECT (SELECT n2.nid 
      FROM node n2 
      WHERE n2.nid = ma.nid 
      AND n2.status = 1 
      LIMIT 1 
     ) AS `nid` 
     , (SELECT n3.title 
      FROM node n3 
      WHERE n3.nid = ma.nid 
      AND n3.status = 1 
      LIMIT 1 
     ) AS `title` 
     , ma.field_article_date_format_value 
     , ma.field_article_summary_value 
    FROM content_type_article ma 
    WHERE EXISTS 
     (SELECT 1 
      FROM node n1 
      WHERE n1.nid = ma.nid 
      AND n1.status = 1 
     )     
    AND EXISTS 
     (SELECT 1 
      FROM term_node tn 
      WHERE tn.nid = ma.nid 
      AND tn.tid = 153 
     ) 
    ORDER BY ma.field_article_date_format_value DESC 
    LIMIT 0,11 

(कभी-कभी "orrelated सबक्वेरी" के इस प्रकार का उपयोग कर एक प्रश्न एक समान क्वेरी कि आपरेशन में शामिल होता है की तुलना में काफी खराब प्रदर्शन हो सकता है। लेकिन कुछ मामलों में, इस तरह एक प्रश्न वास्तव में बेहतर प्रदर्शन कर सकते हैं, विशेष रूप से दिए गए पंक्तियों की एक बहुत ही सीमित संख्या लौटाए जाने)

यहाँ उस क्वेरी के लिए समझाने के उत्पादन है:। जिसका अर्थ है क्वेरी सूचकांक पृष्ठ से सीधे संतुष्ट है

+----+--------------------+-------+-------+---------------+----------------+---------+---------------------+------+--------------------------+ 
| id | select_type  | table | type | possible_keys | key   | key_len | ref     | rows | Extra     | 
+----+--------------------+-------+-------+---------------+----------------+---------+---------------------+------+--------------------------+ 
| 1 | PRIMARY   | ma | index | NULL   | ct_article_ix9 | 27  | NULL    | 11 | Using where; Using index | 
| 5 | DEPENDENT SUBQUERY | tn | ref | term_node_ix9 | term_node_ix9 | 10  | testps.ma.nid,const | 13 | Using where; Using index | 
| 4 | DEPENDENT SUBQUERY | n1 | ref | node_ix9  | node_ix9  | 10  | testps.ma.nid,const | 12 | Using where; Using index | 
| 3 | DEPENDENT SUBQUERY | n3 | ref | node_ix9  | node_ix9  | 10  | testps.ma.nid,const | 12 | Using where; Using index | 
| 2 | DEPENDENT SUBQUERY | n2 | ref | node_ix9  | node_ix9  | 10  | testps.ma.nid,const | 12 | Using where; Using index | 
+----+--------------------+-------+-------+---------------+----------------+---------+---------------------+------+--------------------------+ 
5 rows in set (0.00 sec) 

ध्यान दें कि फिर से, प्रत्येक एक्सेस 'Using index' है, अधिक तत्पर अंतर्निहित तालिका में किसी भी डेटा पेज पर जाने से पहले।

CREATE TABLE `node` (`id` INT PRIMARY KEY, `nid` INT, `title` VARCHAR(10),`status` INT); 
CREATE INDEX node_ix9 ON node (`nid`,`status`,`title`); 
INSERT INTO `node` VALUES (1,1,'foo',1),(2,2,'bar',0),(3,3,'fee',1),(4,4,'fi',0),(5,5,'fo',1),(6,6,'fum',0),(7,7,'derp',1); 
INSERT INTO `node` SELECT id+7,nid+7,title,`status` FROM node; 
INSERT INTO `node` SELECT id+14,nid+14,title,`status` FROM node; 
INSERT INTO `node` SELECT id+28,nid+28,title,`status` FROM node; 
INSERT INTO `node` SELECT id+56,nid+56,title,`status` FROM node; 

CREATE TABLE content_type_article (id INT PRIMARY KEY, nid INT, field_article_date_format_value DATETIME, field_article_summary_value VARCHAR(10)); 
CREATE INDEX ct_article_ix9 ON content_type_article (field_article_date_format_value, nid, field_article_summary_value); 
INSERT INTO content_type_article VALUES (1001,1,'2012-01-01','foo'),(1002,2,'2012-01-02','bar'),(1003,3,'2012-01-03','fee'),(1004,4,'2012-01-04','fi'),(1005,5,'2012-01-05','fo'),(1006,6,'2012-01-06','fum'),(1007,7,'2012-01-07','derp'); 
INSERT INTO content_type_article SELECT id+7,nid+7, DATE_ADD(field_article_date_format_value,INTERVAL 7 DAY),field_article_summary_value FROM content_type_article; 
INSERT INTO content_type_article SELECT id+14,nid+14, DATE_ADD(field_article_date_format_value,INTERVAL 14 DAY),field_article_summary_value FROM content_type_article; 
INSERT INTO content_type_article SELECT id+28,nid+28, DATE_ADD(field_article_date_format_value,INTERVAL 28 DAY),field_article_summary_value FROM content_type_article; 
INSERT INTO content_type_article SELECT id+56,nid+56, DATE_ADD(field_article_date_format_value,INTERVAL 56 DAY),field_article_summary_value FROM content_type_article; 

CREATE TABLE term_node (id INT, tid INT, nid INT); 
CREATE INDEX term_node_ix9 ON term_node (nid,tid); 
INSERT INTO term_node VALUES (2001,153,1),(2002,153,2),(2003,153,3),(2004,153,4),(2005,153,5),(2006,153,6),(2007,153,7); 
INSERT INTO term_node SELECT id+7, tid, nid+7 FROM term_node; 
INSERT INTO term_node SELECT id+14, tid, nid+14 FROM term_node; 
INSERT INTO term_node SELECT id+28, tid, nid+28 FROM term_node; 
INSERT INTO term_node SELECT id+56, tid, nid+56 FROM term_node; 
1

आप वास्तव में से बचना चाहते हैं:


उदाहरण टेबल

यहां उदाहरण के टेबल अपने प्रश्न से जानकारी के आधार पर, कि मैं बनाया गया है और आबादी वाले (अनुक्रमित के साथ) कर रहे हैं यदि आप प्री-सॉर्टेड इंडेक्स का लाभ उठाकर कर सकते हैं तो सॉर्ट ऑपरेशन बिल्कुल हो रहा है।

यह पता लगाने के लिए कि क्या यह संभव है, अपने डेटा को एक तालिका में denormalised कल्पना करें, और सुनिश्चित करें कि आपके WHERE खंड में जो कुछ भी शामिल होना चाहिए वह एक सिंगल VALUE के साथ निर्दिष्ट है। जैसे यदि आपको कॉलम में से किसी एक पर एक खंड का उपयोग करना होगा, तो सॉर्टिंग अपरिहार्य है।

यहां कुछ नमूना डेटा का स्क्रीनशॉट है:

Sample data denormalised and sorted by tid, status DESC, date DESC

तो, अगर आप अपने डेटा denormalised था आप तारीख उतरते द्वारा तरह टीआईडी ​​और स्थिति एकल मूल्यों के प्रयोग पर क्वेरी सकते हैं और फिर। यही कारण है कि मतलब यह होगा कि मामले में निम्नलिखित सूचकांक पूरी तरह से काम करेगा:

create index ix1 on denormalisedtable(tid, status, date desc); 

, तो आप इस किया था, आपकी क्वेरी केवल शीर्ष 10 पंक्तियों पर मारते थे और सॉर्ट करने के लिए की जरूरत कभी नहीं होगा।

तो - कैसे आप denormalising बिना ही प्रदर्शन मिलता है ...

मुझे लगता है कि आप कि MySQL तालिकाओं से चयन करता है मजबूर करने के लिए STRAIGHT_JOIN खंड का उपयोग करने में सक्षम होना चाहिए - आप के लिए इसे पाने के लिए चाहते हैं उस तालिका से चुनें जिसे आप आखिरी बार सॉर्ट कर रहे हैं।

इस प्रयास करें:

SELECT n.nid, 
     n.title, 
     ma.field_article_date_format_value, 
     ma.field_article_summary_value 
FROM node n 
STRAIGHT_JOIN term_node tn   ON n.nid=tn.nid 
STRAIGHT_JOIN content_type_article ma ON n.nid=ma.nid 
WHERE tn.tid= 153 
    AND n.status=1 
ORDER BY ma.field_article_date_format_value DESC 
LIMIT 0, 11; 

विचार MySQL content_type_article मेज से अंत term_node मेज से नोड तालिका से चयन करें और फिर और फिर प्राप्त करने के लिए है (स्तंभ आप पर छँटाई कर रहे हैं युक्त तालिका) ।

यह आखिरी जुड़ाव आपका सबसे महत्वपूर्ण है और आप इसे इंडेक्स का उपयोग करना चाहते हैं ताकि LIMIT क्लॉज डेटा को सॉर्ट करने की आवश्यकता के बिना काम कर सके। ,

create index ix1 on content_type_article(nid, field_article_date_format_value desc); 

या

create index ix1 on content_type_article(nid, field_article_date_format_value desc, field_article_summary_value); 
(एक कवर सूचकांक के लिए)

मैं हो सकता है कहते हैं क्योंकि मैं के बारे में पर्याप्त जानकारी नहीं है:

यह एकल सूचकांक चाल कर सकते हैं MySQL ऑप्टिमाइज़र यह जानने के लिए कि क्या यह एकाधिक 'nid' कॉलम मानों को संभालने के लिए पर्याप्त चालाक है जो सामग्री का उपयोग किए बिना content_type_article में खिलाया जाएगा।

तार्किक रूप से, यह जल्दी से काम करने में सक्षम होना चाहिए - उदा। यदि 5 nid मान अंतिम content_type_article तालिका में खिलाया जा रहा है, तो यह सूचकांक से सीधे प्रत्येक के शीर्ष 10 प्राप्त करने में सक्षम होना चाहिए और परिणामों को एक साथ मिलाएं, फिर अंतिम शीर्ष 10 चुनें, जिसका अर्थ है कि कुल 50 पंक्तियां इस से पढ़ी जाती हैं तालिका जो आप वर्तमान में देख रहे हैं 1 9 006 की स्थापना की।

मुझे बताएं कि यह कैसा चल रहा है।

यदि यह आपके लिए काम करता है, तो पहले दो जुड़ने के लिए अन्य तालिकाओं पर कवर इंडेक्स का उपयोग करके और अधिक अनुकूलन संभव होगा।