J'ai une base de données assez grande - 113 299 lignes dans wp_posts et 216 06649 lignes dans wp_postmeta.
Une des requêtes personnalisées que j'exécute après l'ajout ou la modification d'une publication est affichée dans le fichier de journal lent de MySQL chaque fois qu'elle est exécutée - et semble prendre beaucoup trop de secondes (entre 17 et 78 secondes en fait).
Voici à quoi cela ressemble dans query_posts
:
$args = array(
'meta_query' => array(
array(
'key' => 'article_template',
'value' => 'news',
),
),
'posts_per_page' => '30',
'category__in' => array( 3, 4, 5 ),
'post_status' => 'publish',
'no_found_rows' => true,
'orderby' => 'meta_value',
'meta_key' => 'article_datetime',
'order' => 'DESC'
);
query_posts( $args );
Et voici à quoi cela ressemble dans le fichier de journal lent de MySQL:
SELECT wp_posts.ID FROM wp_posts INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) INNER JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id)
INNER JOIN wp_postmeta AS mt1 ON (wp_posts.ID = mt1.post_id) WHERE 1=1 AND ( wp_term_relationships.term_taxonomy_id IN (3,4,5) ) AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish') AND (wp_postmeta.meta_key = 'article_datetime'
AND (mt1.meta_key = 'article_template' AND CAST(mt1.meta_value AS CHAR) = 'news') ) GROUP BY wp_posts.ID ORDER BY wp_postmeta.meta_value DESC LIMIT 0, 30;
Voici ce que EXPLAIN montre pour cette requête:
mysql> explain SELECT wp_posts.ID FROM wp_posts INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) INNER JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id)
-> INNER JOIN wp_postmeta AS mt1 ON (wp_posts.ID = mt1.post_id) WHERE 1=1 AND ( wp_term_relationships.term_taxonomy_id IN (3,4,5) ) AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish') AND (wp_postmeta.meta_key = 'article_datetime' AND (mt1.meta_key = 'article_template' AND CAST(mt1.meta_value AS CHAR) = 'news') ) GROUP BY wp_posts.ID ORDER BY wp_postmeta.meta_value DESC LIMIT 0, 30;
+----+-------------+-----------------------+--------+--------------------------+----------+---------+-----------------------------+-------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------------------+--------+--------------------------+----------+---------+-----------------------------+-------+----------------------------------------------+
| 1 | SIMPLE | wp_postmeta | ref | post_id,meta_key | meta_key | 768 | const | 98576 | Using where; Using temporary; Using filesort |
| 1 | SIMPLE | wp_posts | eq_ref | PRIMARY,type_status_date | PRIMARY | 8 | toi_web.wp_postmeta.post_id | 1 | Using where |
| 1 | SIMPLE | mt1 | ref | post_id,meta_key | post_id | 8 | toi_web.wp_postmeta.post_id | 11 | Using where |
| 1 | SIMPLE | wp_term_relationships | ref | PRIMARY,term_taxonomy_id | PRIMARY | 8 | toi_web.mt1.post_id | 2 | Using where; Using index |
+----+-------------+-----------------------+--------+--------------------------+----------+---------+-----------------------------+-------+----------------------------------------------+
Je me demande donc si quelqu'un a un bon conseil ou une suggestion pour l'optimiser et éviter la requête lente? Peut-être que casser cela dans une boucle query_posts
différente? Ou tout d’abord, récupérez les ID des publications avec une simple requête wpdb->get_results
?
Je suis ouvert à toute suggestion :)
À propos, nous avons un cluster MySQL très robuste, donc les ressources du serveur ne sont pas le problème .
Si la requête est toujours lente, alors supprimez:
'orderby' => 'meta_value', 'meta_key' => 'article_datetime', 'order' => 'DESC'
et au lieu de cela trier le résultat dans php.