Comment optimiser le site WP pour des millions de messages

19

Je travaille sur un site Web pour une entreprise qui créera très probablement des millions de publications via un type de publication personnalisé. Ce sont des prières, donc, fondamentalement, l'utilisateur du front-end soumet simplement une courte phrase via un formulaire. Tout ce qui compte pour l'entreprise, c'est le contenu de la publication et la date de publication. Le site n'a même pas encore été lancé et ils ont déjà plus de 120 000 messages, donc je suis très sérieux quand je dis des millions.

Donc, quelques questions d'optimisation:

  1. Disons que j'ai une catégorie «en vedette» dans un type de message personnalisé qui compte 500 000 messages. La catégorie sélectionnée ne compte que 500 messages. Si je crée une requête pour les articles en vedette, est-ce que j'interroge l'intégralité des 500 000 articles, ou seulement les 500 articles en vedette? Que se passe-t-il si je souhaite afficher uniquement les dix articles les plus récents présentés?
  2. Lors de l'enregistrement de ce type de publication personnalisé dans la base de données, puis-je faire des choses pour réduire les ressources du serveur, d'autant plus que la seule chose vraiment nécessaire est le contenu de la publication et la date?
  3. Dois-je même utiliser un type de message personnalisé? Je l'aime en principe car il est bien intégré dans l'administrateur WordPress, mais s'il y a des inconvénients importants dans les performances, je suppose que je peux faire quelque chose de différent.

Je n'ai jamais travaillé sur un projet à cette échelle, donc je suis un peu plus préoccupé par les performances que d'habitude. Merci pour toute aide!

Jeremiah Prummer
la source
Il est important de réduire au minimum les requêtes de base de données dans vos fonctions WordPress et d'appeler les scripts de manière appropriée, mais une grande partie de l'optimisation a à voir avec la façon dont le serveur est installé et configuré. Pour cela, recherchez le réseau Server Fault. serverfault.com/search?q=optimize+wordpress
iyrin
@RyanLoremIpsum - merci pour le commentaire, mais j'espérais des réponses pour mes questions spécifiques. La plupart de ce que j'y ai trouvé concerne le serveur lui-même, pas comment WordPress fonctionne et comment l'optimiser du point de vue du code
Jeremiah Prummer

Réponses:

26

1. Définissez la requête avant l' exécution de WP_Query

Cela semble être la chose la plus importante à garder à l'esprit lorsque vous essayez de réduire au minimum les requêtes de base de données, car la seule possibilité de modifier la requête est, bien sûr, avant qu'elle ne soit exécutée dans la base de données SQL.

Requêtes normales
Pour une requête normale, WordPress utilise la wp()fonction, qui à son tour appelle $wp->main( $query_vars ). Les «variables is_» des balises conditionnelles sont définies avant de les passer à WP_Query->get_posts(), ce qui la convertit en une requête de base de données MySQL et les stocke finalement dans l'objet $ wp_query. Il est possible de filtrer la requête avant qu'elle ne soit réellement exécutée dans la base de données SQL .

L' pre_get_postsaction se connecte à ce processus, vous permettant de modifier la requête avant de la transmettre WP_Query->get_posts().

Par exemple, si vous souhaitez filtrer la requête pour les articles de la catégorie "en vedette", vous devez utiliser add_action( 'pre_get_posts', 'your_function_name' );et inclure la in_categorybalise conditionnelle dans your_function_name.

function your_function_name( $query ) {
    if ( $query->in_category( 'featured' ) && $query->is_main_query() ) {
        // Replace 123 with the category ID of the featured category.
        $query->set( 'cat', '123' );
    }
}
add_action( 'pre_get_posts', 'your_function_name' );

Voir Plugin API / Action Reference / pre get posts «WordPress Codex

Demandes
de page Comme pour les modèles de page, comme la page d'archive pour la catégorie "sélectionnée", les balises conditionnelles ne fonctionneront pas à partir du pre_get_postsfiltre. Par exemple, vous ne pouvez pas utiliser is_categorypour vérifier la page d'archive car WP_Query ne s'est pas exécuté.

Au lieu de cela, vous devrez modifier la requête principale pour les demandes de page avec un new WP_Queryqui ressemblerait à quelque chose $query = new WP_Query( 'cat=123' );. Cela exécute la requête avec l'argument approprié défini depuis le début.

Voir Référence de classe / Requête WP «WordPress Codex

2. Enregistrement dans la base de données

Vous pouvez utiliser le filtre en vous wp_insert_post_dataassurant que seules les données $ pertinentes pour votre type de publication personnalisé sont renvoyées wp_insert_post. Assurez-vous d'inclure une déclaration conditionnelle pour vérifier votre type de publication personnalisé.
Plugin API / Filter Reference / wp insert post data «WordPress Codex

Ce hook est appelé par la wp_insert_postfonction, qui est appelée par wp_update_post lorsque vous mettez à jour votre type de publication personnalisé, généralement en enregistrant un brouillon ou en publiant la publication.

Vous devrez le comparer vous-même, car je ne peux pas parler personnellement de l'importance de l'optimisation de la réduction des données mises à jour dans la base de données.

3. Les types de publication personnalisés affectent-ils les performances?

D'après mon expérience, les types de publication personnalisés sont un outil puissant pour gérer le contenu. Je ne connais pas d'autre moyen de gérer les messages de toutes les manières qu'il autorise d'une manière qui utiliserait moins de ressources. Je me concentrerais personnellement sur la recherche de moyens de réduire le nombre de requêtes effectuées dans la mesure du possible.

Il y avait auparavant un problème de performances lié à la structure du permalien, ce qui provoquait un coup quand il commençait par du texte au lieu d'un nombre. 3 Cela était particulièrement gênant pour les sites hébergeant un grand nombre de pages, mais a été résolu depuis WordPress version 3.3.

Je ne fais apparaître que des permaliens ici parce que le slug est généralement la première partie de la structure de permaliens qui peut ou non avoir affecté les performances avant la version 3.3. En dehors de cela, je ne suis au courant d'aucun problème de performances lié à l'utilisation de types de publication personnalisés.

Autres options de performances

Transitoires
Ce n'est pas un remplacement pour garder les requêtes au minimum dans votre code, mais vous pouvez utiliser set_transient pour stocker les requêtes pendant un certain temps afin que de nouvelles requêtes ne soient pas nécessaires. Voici l'exemple utilisé dans le billet de Dave Clements . Notez également qu'il recommande d'ajouter une save_postaction pour supprimer le transitoire chaque fois qu'un type de message donné est mis à jour.

<?php // IN THE SPOTLIGHT QUERY
if( false === ( $its_query = get_transient( 'its_query' ) ) ) {
    $pttimestamp = time() + get_option('gmt_offset') * 60*60;
    $its_query = new WP_Query( array(
        'post_type' => 'spotlight',
        'posts_per_page' => 1,
            'post__not_in' => $do_not_duplicate,
        'meta_query' => array(
            array(
                'key' => '_hpc_spotlight_end_time',
                'value' => $pttimestamp,
                'compare' => '>'
            )
        )
    ) );
    set_transient( 'its_query', $its_query, 60*60*4 );
}
if( have_posts() ) { // HIDE SECTION IF NO CURRENT ITS FEATURE ?>
    // LOOP GOES HERE: NOT IMPORTANT TO EXAMPLE
<?php } ?>

Plus d'optimisation des requêtes
Thomas Griffin a quelques bons conseils dans son tutoriel Optimiser les requêtes WordPress . Voici une brève liste de ses suggestions:

  • Définissez 'cache_results' => falsedes requêtes uniques si votre serveur n'utilise pas la mise en cache persistante telle que Memcached. Les requêtes ponctuelles sont décrites comme des «requêtes utilisées pour afficher de petites quantités de données. Il se peut que vous souhaitiez simplement afficher les titres de publication liés à la publication actuelle, ou vous souhaitiez afficher une liste déroulante de publications à sélectionner pour une option particulière. "

    Son exemple: $query = get_posts( array( 'posts_per_page' => 1, 'cache_results' => false ) );

  • Définissez 'no_found_rows' => trueoù la pagination n'est pas nécessaire. Cela "contournera MySQL en comptant les résultats pour voir si nous avons besoin de pagination ou non."

    Son exemple: $query = new WP_Query( array( 'posts_per_page' => 1, 'no_found_rows' => true ) );

  • Requête pour les ID de poste que si cela est tout ce que vous avez besoin 'fields' => 'ids' dans get_posts. Cela devrait réduire considérablement la quantité de données retournées, ce qui est beaucoup par article si vous regardez la description de la base de données «WordPress Codex

    Son exemple: $query = get_posts( array( 'posts_per_page' => 1, 'fields' => 'ids' ) );

En plus de ce dernier conseil, le même raisonnement peut être appliqué lorsque vous n'avez besoin que d'un ou de quelques champs de publication en utilisant get_post_field .

Il est essentiel de bien comprendre le fonctionnement de la requête. Plus vous pouvez être précis avec vos requêtes, moins vous demanderez de travail à votre base de données SQL. Cela signifie qu'il existe un grand nombre de possibilités pour gérer les requêtes de base de données. Soyez prudent avec les requêtes personnalisées dans la mesure où elles s'exécutent (est-ce une page d'administration?), Utilisez une désinfection appropriée dans les requêtes directes et essayez d'utiliser des fonctions WordPress natives où cela vous permet d'obtenir les mêmes performances.

iyrin
la source
2
Réponse excellente et extrêmement utile, merci!
Jeremiah Prummer
Le thème est entièrement personnalisé, nous ne demandons donc littéralement que les éléments absolument essentiels. Ils sont cependant extrêmement utiles. Compte tenu de cela, je vais revenir en arrière et apporter des modifications à mes requêtes. ;)
Jeremiah Prummer
1
J'ajoute que vous devriez éviter les méta-requêtes autant que possible. N'exécutez certainement pas une requête sur deux champs méta simultanément. Il en résulte des requêtes doubles et triples qui deviennent rapidement un nigtmare de performance. Les types de publication personnalisés peuvent souvent aider à cela.
Charles Jaimet
3

J'ajoute également:

    'no_found_rows'          => true,
    'update_post_term_cache' => false,
    'update_post_meta_cache' => false,
    'cache_results'          => false
  • no_found_rows (boolean) - rendez-le vrai lorsque vous n'avez besoin d'aucune pagination et n'avez pas besoin du décompte du nombre total de publications trouvées.
  • cache_results (boolean) - Publie le cache d'informations.
  • update_post_meta_cache (boolean) - Publie le cache des méta-informations.
  • update_post_term_cache (boolean) - Cache d'informations post-terminales.

En utilisant ces paramètres et en transmettant des valeurs comme FAUX, nous pouvons accélérer la requête en arrêtant l'exécution de quelques requêtes de base de données supplémentaires.

Remarque: Nous ne devons pas toujours utiliser ces paramètres car l'ajout de choses au cache est la bonne chose à faire, mais ceux-ci peuvent être utiles dans des circonstances spécifiques et vous devriez envisager de les utiliser lorsque vous savez ce que vous faites.

Veuillez visiter: https://drujoopress.wordpress.com/2013/06/27/how-to-optimize-wordpress-query-to-get-results-faster/#more-184

rigosan
la source
1
Veuillez modifier votre réponse et ajouter une explication: pourquoi cela pourrait-il résoudre le problème?
fuxia
Je ne peux pas ajouter mon commentaire sur cette réponse: wordpress.stackexchange.com/a/166699/57674
rigosan
1

Comme tous les types de questions d'optimisation prématurée, il est impossible de répondre à cette question sans connaître les modèles d'utilisation exacts qui, trop souvent, ne sont découverts que lorsque vous êtes en ligne.

En général, selon les spécifications MYSQL, il ne devrait pas y avoir de problème avec la quantité de données. Bien sûr, la recherche de données, même avec les meilleurs algorithmes, sera plus lente qu'avec des tables beaucoup plus petites, mais la solution est un processeur simple et plus puissant.

Vous souhaiterez peut-être optimiser la façon dont les métadonnées sont stockées (par exemple, pour ne pas stocker les données liées au ping), mais ce genre de chose dépend de ce que vous faites exactement, et à la fin, vous aurez peut-être encore besoin d'un processeur plus puissant, ce qui ne vaut peut-être pas la peine .

Mark Kaplun
la source