Réduction du nombre de requêtes SQL

Eléphanteau du PHP | 11 Messages

23 janv. 2017, 21:11

Bonsoir,

Mon premier "vrai" site web, codé de mes propres mains (sous Wordpress, avec un thème 100% home made et quelques plugins maisons) arrive bientôt en phase de production. Ayant appris sur le tas, en autodidacte, les rouages de PHP et Wordpress, il y a cependant certaines choses qui me sont passées entre les doigts.

C'est pourquoi j'ai une petite question : voyant une certaine redondance dans plusieurs de mes fonctions, je me disais qu'il y a avait surement un ou plusieurs moyen(s) possible(s) pour éviter les requêtes en double, triple voire quadruple. Lesquels sont-ils?

Exemple typique dans mon projet, l'utilisation de ce code simple me permettant de récupérer le type de post en cours :

Code : Tout sélectionner

$post_type = get_post_type($post)
Dans plusieurs de mes fonctions, je défini cette variable. Et souvent, lorsqu'une page est générée, elle peut contenir 3 ou plus de ces fonctions, et vont donc toutes faire une requête pour au final... la même donnée.

J'aimerais me débarrasser de ces doublons, et aimerais donc connaitre les moyens pour y arriver. Y a-t-il possibilité de déclarer dans un fichier unique certaines variables couramment utilisées? Ou peut-être devrais-je pencher sur la déclaration de variables globales/super_globales. Toute aide serait le bienvenu.

Merci.

Eléphanteau du PHP | 22 Messages

23 janv. 2017, 22:15

Bonsoir,
Une boucle en début de page est peut être la solution celle-ci me permet de visualiser les variables on peut aussi ajouter un traitement ex: get
foreach($_POST as $key => $val){ echo '<br>$_POST['.$key.']='.$val.'';} /*boucle affichage post*/

Eléphanteau du PHP | 11 Messages

23 janv. 2017, 22:29

Merci pour la réponse Bernard_2102, mais je me demande où est la réponse à ma question là dedans lol

Pouvoir visualiser les variables est une chose, diminuer les redondances directement dans les requêtes en est une autre. Je ne cherche pas à visualiser en frontend les requêtes en doublons, mais je cherche plutôt à déclarer une variable de manière globale afin qu'elle soit utilisable partout dans mon code sans avoir à redéclarer celle-ci... si toutefois ce n'est pas contre-productif (car j'ai souvent lu qu'utiliser des globales ou super globales n'étaient pas toujours une bonne pratique).

Où alors ai-je manqué quelque-chose?

Eléphanteau du PHP | 22 Messages

24 janv. 2017, 00:06

Effectivement je suis hors sujet je n'ai jamais utilisé wordpress, quand j'ai une variable importante je la passe en variable de session et quand je veut y faire référence je passe je passe un & , à voir si ça fonctionne avec wordpress?
$post_type = get_post_type(&$post)

Eléphanteau du PHP | 22 Messages

24 janv. 2017, 11:49

pour info le & n'est pas à positionner dans l’appel de la fonction mais dans sa définition ce qui permet d'utiliser les valeurs des variables en dehors de la fonction mais si tu les modifies dans ta fonction elles sont également modifié à l'extérieure.
ex:
$post=1;
function get_post_type(&$post)
{ $post ++;
echo "<br> \$post = ".$post;} 

get_post_type($post);//$post = 2

get_post_type($post);//$post = 3

Mammouth du PHP | 1967 Messages

24 janv. 2017, 12:13

Il y a un système de cache dans wordpress qui limite les requète, si tu regarde le code de ces fonctions natives de WP, tu verra qu'elle font elle même appel à des superglobale.
https://developer.wordpress.org/referen ... post_type/
https://developer.wordpress.org/referen ... /get_post/

J'ajouterai que dans le cas d'un CMS, le mieux est de faire appel à un maximum de fonction native car elle gère probablement un cache. mettre toi même en cache ce type de donnée n'est pas une bonne idée, lors d'une maintenance, si tu dois modifier quelque chose d'une variable globale, il te faudra retrouver où tu l'a déclarer etc. alors que si tu continue à utiliser la fonction native, c'est le coeur du système WP qui s'en chargera. De plus, il peut être beaucoup plus simple de comprendre l'appel à une fonction native que ta fonction perso pour quelqu'un d'autre qui devrait mettre le nez dans ton code.

Si tu as beaucoup de plugin perso, certain aurait peut être besoin d'un système de cache du même style selon leur utilité et leur usage.

Désolé pour Bernard_2102, mais tes réponses sont hors sujet.
Spols
pour les fan de rubik's cube ou pour les curieux ==> le portail francophone du rubik's cube

Eléphanteau du PHP | 11 Messages

24 janv. 2017, 13:02

Merci pour la réponse Spols.

Concernant le cache des fonctions natives, c'est une bonne remarque. Cependant, dans mon code, la variable associée à ce get_post_type() est tantôt $current_cpt, tantôt $cpt_in_use ou encore $actual_post_type (me demande pas pourquoi, je n'ai pas vraiment cherché à avoir les mêmes noms de variables pour un résultat donné). Et du coup, vu que le nom de la variable change, je m'étais dis que le cache allait être généré 3 fois pour ces 3 variables. Mais je me trompe peut-être, et ce qui est mis en cache ne sera pas la variable, mais le résultat de la requête SQL c'est bien ça?

A vrai dire, avant ton post, j'étais en train de pencher sur la création d'un fichier unique contenant mes variables globales, que j'aurais inclus avec un require_once dans mon functions.php (mon functions.php étant exclusivement constitué de require_once, vu que j'ai opté pour la segmentation de mon code en fichiers).

Voici à quoi ressemble mon functions.php actuellement :

Code : Tout sélectionner

<?php /*------------------------------------------------------------------------------ FRONTEND ------------------------------------------------------------------------------*/ // #1 - Structure HTML globale require_once( get_stylesheet_directory() . '/template-elements/frontend/global-html-structure.php' ); // #2 - Menu // Menu principal require_once( get_stylesheet_directory() . '/template-elements/frontend/menu/main-menu.php' ); // Menu secondaire et hyperliens associés require_once( get_stylesheet_directory() . '/template-elements/frontend/menu/sub-menu-cpt.php' ); // #3 - Grids (Queries associées et génération HTML) require_once( get_stylesheet_directory() . '/template-elements/frontend/grids.php' ); // #4 - Info-box (CPT, taxonomies, plateformes, liens commerciaux) require_once( get_stylesheet_directory() . '/template-elements/frontend/info-box.php' ); // #5 - Tabs commentaires et alternatives require_once( get_stylesheet_directory() . '/template-elements/frontend/tabs-alternatives-comments.php' ); // #6 - Sidebars require_once( get_stylesheet_directory() . '/template-elements/frontend/sidebar.php' ); // #7 - Contenu conditionnel require_once( get_stylesheet_directory() . '/template-elements/frontend/conditional-content.php' ); /*------------------------------------------------------------------------------ BACKEND ------------------------------------------------------------------------------*/ // #1 - Enqueue & register-cpt // Register Custom Post Types require_once( get_stylesheet_directory() . '/template-elements/backend/enqueue-and-register/register-cpt.php' ); // Register Taxonomies require_once( get_stylesheet_directory() . '/template-elements/backend/enqueue-and-register/register-taxonomies.php' ); // Register Sidebar require_once( get_stylesheet_directory() . '/template-elements/backend/enqueue-and-register/register-sidebars.php' ); // Enqueue Styles & Scripts require_once( get_stylesheet_directory() . '/template-elements/backend/enqueue-and-register/styles-scripts-enqueue.php' ); // #2 - Save-post actions require_once( get_stylesheet_directory() . '/template-elements/backend/automatisation/save-post-actions.php' ); // #3 - Paramètres des images require_once( get_stylesheet_directory() . '/template-elements/backend/thumbnails-settings.php' ); // #4 - Tweaks require_once( get_stylesheet_directory() . '/template-elements/backend/wp-tweaks.php' ); // #5 - Fonctions custom génériques require_once( get_stylesheet_directory() . '/template-elements/generic-custom-functions.php' ); // #6 - Duplication de post require_once( get_stylesheet_directory() . '/template-elements/backend/post-duplication.php' ); // #7 - Actions & filtres => upload image require_once( get_stylesheet_directory() . '/template-elements/backend/automatisation/img-upload-actions.php' );
D'un point de vue pratique, ça aurait été top : ce fichier central m'aurait permit de déclarer mes variables les plus utilisées, afin de les appeler directement sans avoir à tout redéclarer. La lisibilité du code aurait été parfaite au regard de la segmentation en fichiers séparés originelle de mon code, et j'y aurai gagné aussi en terme de productivité/maintenance avec des variables globales explicites et facilement mémorisable.

J'ai une dernière question : d'un point de vue technique, j'aimerais connaitre les inconvénients d'une variable globale. J'ai souvent lu que ce n'était pas forcément une bonne pratique et me demande bien pourquoi.

Mammouth du PHP | 1967 Messages

24 janv. 2017, 14:17

Oui l'important est plus de minimiser les requète plutot que les appels à des globales.

Je suis pas expert en WP, j'ai jamais fait tourner un site dessus je travail qu'avec Drupal. Mais j'ai l'impression que tu n'a pas un plugin par fonctionnalité ajoutée. Ce qui veut dire que tu peux avoir des interdépendences qui pourront s'avèrer problèmatique par la suite.
Le mieux c'est de faire des plugin les plus indépendant possible et limité les dépendances à un arbre linéaire.

Centralisé des variables peut te sembler un bon plan, mais si tu dois retourner dans ton code plusieurs mois plus tard, tu ne te rappellera pas nécéssairement quelles variables est déclarée où. il vaut mieux définir une logique et s'y tenir.

les variables globales peuvent prendre beaucoup de place mémoire. charger toutes ces variables à chaque fois si elle sont inutiles peut prendre des ressources qui serait libre sinon.
Spols
pour les fan de rubik's cube ou pour les curieux ==> le portail francophone du rubik's cube

Eléphanteau du PHP | 11 Messages

24 janv. 2017, 14:34

OK bien noté. Dernière question : Une fiche produit (correspondant à mes post les plus gourmands) fait en moyenne 200 requêtes dans la base de données. Avec les quelques ajouts que je compte faire pour finaliser le tout, j’atteindrais je pense les 250/300 requêtes SQL.

Cela semble-t-il acceptable, sachant que je fais des requêtes pour 4 taxonomies par fiche (niveau I, niveau 2, niveau 3...), + plusieurs requêtes pour des custom fields (date de sortie, note de presse web, nom de l'éditeur...), des screenshots, commentaires etc... Bref, pour une fiche complète de ce type https://www.les-alternatives.com/logici ... nter/kodi/, est-ce que je me situe dans une bonne tranche?

Ca peut parraitre bête comme question, mais je préfère optimiser le code en amont, avant le lancement du projet, pour qu'il soit dans une tranche acceptable plutôt que de devoir être confronté à des problèmes en phase de production.

Merci encore, et bonne journée.

Mammouth du PHP | 1967 Messages

24 janv. 2017, 15:19

je suis pas expert dans le domaine, j'ai trouvé ceci (ca parle de drupal mais c'est dans le thème de ta question)
https://groups.drupal.org/node/18411#comment-63386

Comment compte tu les requètes ? manuellement ou tu as un log ou un "watchdog" ? WP a surement un système de cache également, tu peux voir comment l'utiliser pour tes plugin perso. mais comme dit dans le lien, est-ce que cela pose déjà un problème ?
J'ai un jour lu un principe de dévellopement: chaque dévellopement doit répondre à un besoin pas une éventualité future incertaine.
ou ne passe pas ton temps à prévoir ce que ton script pourrait faire plus tard, contente toi de faire en sorte qu'il marche
Spols
pour les fan de rubik's cube ou pour les curieux ==> le portail francophone du rubik's cube

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

24 janv. 2017, 15:27

@spols : cela revient un peu à YAGNI :-)
ceci dit un minimum d'optimisation ne nuit pas :)

@Mooks : peux être qu'un forum dédié WP serait plus a même de te répondre ? par exemple https://wpfr.net/support/

@+
Il en faut peu pour être heureux ......

Eléphanteau du PHP | 11 Messages

25 janv. 2017, 03:19

Bon, vous avez bien résumé la situation... à savoir que je chipote trop :p Je veux tellement bien faire et tellement appliquer les bonnes pratiques que j'en perd l'essentiel : faire que ça fonctionne.

Sur mon site tout va bien, mes 200 requêtes database prennent environ 0.3s à 0.5s, auquel se rajoute le délai du first byte received, et les autres requêtes serveurs pour les images, scripts et css. Je tourne à moins de 2 secs de page load si l'on se situe à 1000km ou moins de l'emplacement de mon serveur, qui se trouve en Suisse. Tout va bien donc...

Ce thread sur les requêtes database vient du fait que mon site, proposant pour chaque fiche produit une liste d'alternatives crédibles, va faire dans un future très proche de très nombreuses requêtes... vu que mon site va être une véritable base de données de milliers de produits. Donc voilà pourquoi je voulais l'optimiser au maximum.

La principale chose que je retiens, c'est l'importance de la mise en cache, ainsi que l'inspection des requêtes les plus longues à s'éxécuter pour les optimiser. Mais le nombre de requêtes SQL ne semble pas un critère important.

Merci à tous pour vos réponses, je repasserais sous peu histoire d'avoir vos avis en terme d'expérience utilisateur d'ici quelques semaines. Bye.