Sto utilizzando Drupal 6 con MySQL versione 5.0.95 e in un'impasse in cui una delle mie query che visualizza i contenuti in base alla data di articolo più recente rallenta ea causa del la frequenza di utilizzo uccide del tutto le prestazioni del sito. La query in questione è il seguente:Impossibile ottimizzare la query MySQL che utilizza una clausola ORDER BY
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;
La EXPLAIN della query mostra il risultato qui sotto:
+----+-------------+-------+--------+--------------------------+---------+---------+----------------------+-------+---------------------------------+
| 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 |
+----+-------------+-------+--------+--------------------------+---------+---------+----------------------+-------+---------------------------------+
Questa query sembrava relativamente semplice e diretto e recupera gli articoli che appartengono ad una categoria (termine) 153 e sono di stato 1 (pubblicato). Ma a quanto pare Usando la tabella temporanea e Usando filesort si intende che la query è destinata a fallire da ciò che ho imparato navigando a riguardo.
La rimozione di field_article_date_format_value dalla clausola ORDER BY risolve l'utilizzo temporaneo; L'uso di filesort riduce il tempo di esecuzione della query ma è richiesto e non può essere scambiato, sfortunatamente lo stesso vale anche per le prestazioni del sito.
La mia impressione è che gran parte del problema deriva dalla tabella term_node che mappa gli articoli in categorie ed è una tabella di relazioni a molti molti che significa se l'articolo X è associato a 5 categorie C1 .... C5 avrà 5 voci in quella tabella, questa tabella proviene da drupal out-of-the-box.
lotta contro i contenuti pesanti DB è qualcosa di nuovo per me e passando attraverso alcune delle domande rivolte simili ( When ordering by date desc, "Using temporary" slows down query, MySQL performance optimization: order by datetime field) ho cercato di creare un indice composto per il content_type_article cui campo datetime viene utilizzato nella clausola ORDER BY lungo con un'altra chiave (nid) e tentò di forzare l'INDICE.
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;
Il risultato e la seguente interrogazione EXPLAIN non sembra aiutare molto
+----+-------------+-------+--------+--------------------------+-----------------+---------+----------------------+-------+---------------------------------+
| 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 |
+----+-------------+-------+--------+--------------------------+-----------------+---------+----------------------+-------+---------------------------------+
campi n.nid, ca.nid, ma.field_article_date_format_value sono tutti indicizzati. Interrogare il DB con Limite 0,11 richiede circa 7-10 secondi con la clausola ORDER BY, ma senza di esso la query impiega a malapena un secondo. Il motore del database è MyISAM. Qualsiasi aiuto su questo sarebbe molto apprezzato.
Qualsiasi risposta che potrebbe aiutarmi a ottenere questa query come una normale (alla stessa velocità di una query senza ordinamento per data) sarebbe ottima. I miei tentativi con la creazione di una query composita come combinazione di nid
e field_article_date_format_value
e l'utilizzo nella query non hanno aiutato la causa. Sono aperto a fornire ulteriori informazioni sul problema e su eventuali nuovi suggerimenti.
Grazie per la risposta, sebbene il term_nodo sia N: N i nodi risultanti per un particolare termine saranno distinti nel mio caso .. Ho provato l'approccio della tabella derivata in precedenza ma l'esecuzione della query era quasi la stessa di quella convenzionale . – optimusprime619