Pourquoi optimiser les requêtes Doctrine ?

Publié le par Sacri

Bonjour à tous !

Et oui, me revoilà après plusieurs mois sans post. Il faut dire qu'entre le boulot, les cours du soir et le sport, le temps est assez limité pour le reste ! Mais bon, je profite d'avoir un petit moment pour vous faire partager une expérience qui, pour beaucoup, semble évidente mais à laquelle on ne pense pas suffisament : Optimiser une requête Doctrine

Dans l'admin generator, on pense souvent à modifier la requête de sélection de Doctrine (pour l'affichage de la liste) en intégrant des leftJoin ou innerJoin (ceux qui ne le font pas encore, pensez-y !).

Je le fais toujours mais dans mes modules de frontend (en général, de l'affichage de données en base), je ne le faisais pas (sans doute parce que mes requête étaient simples).
Sur un projet, j'ai pu découvrir le bénéfice non négligeable d'optimiser la requête d'affichage des données, que ce soit au niveau du nombre de requêtes mais également au niveau du temps d'affichage de la page (plus précisément, au niveau du temps de calcul de l'actin d'index).

Pour que ce soit plus parlant, regardons quelques printscreen :
- utilisation de la requête générée par Doctirne




- utilisation d'une requête (et d'une action) optimisée




Voilà, je pense que c'est suffisamment parlant non ?
Pour information, j'ai rafraichi plusieurs fois la page afin d'obtenir des valeurs lorsque le cache est utilisé.

En non optimisé, Doctrine effectue 129 requêtes (3.98ms) et une fois optimisée, UNE seule requête est effectuée (0.01ms).
Le temps étant en ms, c'est assez négligeable certes mais pour une base de données énorme avec beaucoup d'accès, le ratio est de 400 ! De plus, le fait d'avoir un certain nombre de requêtes (hydratation de base Objet) rentre en compte dans le temps de calcul de l'action dont elle dépend et ici, le ratio est encore important 6 !

Afin de vous ouvrir un peu plus les yeux, il faut voir le schema de la base afin de comprendre la "complexité" des relations : schema.yml
Voici également la requête optimisée (je ne sélectionne que les données nécessaires et j'hydrate en array afin de limite les ressources nécessaires et sachant qu'il s'agit d'affichage de données, c'est parfait !) : TacheTable.class.php
Et pour finir, je vous propose les deux actions (en premier, l'action optimisée avec l'hydratation array et en second, l'ancienne action avec l'hydratation objet) : actions.class.php

Voilà, je pense que c'est assez explicite, j'obtiens exactement le même rendu avec l'une ou l'autre des actions et des requêtes et j'avoue avoir été vraiment impressionné sur ce coup là !
Morale : toujours chercher à optimiser ses requêtes !

Publié dans Astuce

Commenter cet article

Damien 04/01/2010 21:17


Ah ok merci pour l'explication!


Damien 04/01/2010 18:42


Je ne comprends pas pourquoi cela ne doit être utilisé uniquement pour de l'affichage?


Sacri 04/01/2010 20:12


Bonsoir,
En fait, l'hydratation en array ne permet pas de retravailler l'objet en lui même pour le sauvegarder ou le modifier.
Tu peux créer ta méthode sans l'hydratation en array et si tu en as besoin pour de la modification, tu ne touches rien et si c'est juste pour de l'affichage, tu l'hydrate en array?


Damien 03/01/2010 23:29


Article très intéressant, le gain de performance est ahurissant avec si peu de modifications.
Merci!


Sacri 04/01/2010 14:48

Bonjour, j'avoue avoir été bluffé lorsque j'ai vu la différence! Pour la plupart des cas, c'est intéressant mais pas toujours. Il faut bien vérifier que ce n'est que pour de l'affichage.