Mysql
 sql >> Base de données >  >> RDS >> Mysql

Doctrine Paginator sélectionne le tableau entier (très lent) ?

Vous devriez simplifier votre requête. Cela réduirait le temps d'exécution. Je ne peux pas tester votre requête, mais voici quelques conseils :

  • ne pas trier lors de l'exécution de count()
  • vous pouvez trier par orderBy('p.id', 'DESC') , l'index serait utilisé
  • au lieu de leftJoin() vous pouvez utiliser join() si au moins un enregistrement existe toujours dans la table jointe. Sinon, cet enregistrement est ignoré.
  • KNP/Paginator utilise DISTINCT() pour lire uniquement des enregistrements distincts, mais cela peut conduire à l'utilisation de la table disk tmp
  • $query->getArrayResult() utilise le mode hidration de tableau, qui renvoie un tableau multidimensionnel et il est beaucoup plus rapide que l'hidration d'objet pour un grand ensemble de résultats
  • vous pouvez utiliser partial select('partial p.{id, other used fields}') , de cette façon, vous ne chargeriez que les champs nécessaires, en ignorant peut-être les relations inutiles lors de l'utilisation de l'hydratation d'objet
  • vérifier SF profiler EXPLAIN sur une requête donnée sous la section doctrine, peut-être que les index ne sont pas utilisés
  • est-ce que p.hashtags et p.likes renvoient une seule ligne ou est oneToMany, ce qui multiplie le résultat
  • peut-être que certaines modifications de conception des publications supprimeraient certaines jointures :
    • avoir un champ p.hashtags défini comme @ORM\Column(type="array") et ont stocké des valeurs de chaîne de balises. Plus tard, peut-être utiliser la recherche plein texte sur un tableau sérialisé.
    • avoir le champ p.likesCount défini comme @ORM\Column(type="integer") qui compterait des likes

J'utilise KnpLabs/KnpPaginatorBundle et peut également avoir des problèmes de vitesse pour les requêtes complexes.

Habituellement, l'utilisation de LIMIT x,z est lente pour la base de données, car elle exécute COUNT sur l'ensemble de données. Si les index ne sont pas utilisés, c'est extrêmement lent.

Vous pouvez utiliser une approche différente et faire une pagination personnalisée par identification, mais cela compliquerait votre approche. Je l'ai utilisé avec de grands ensembles de données comme les tables SYSLOG. Mais vous perdez la fonctionnalité de tri et de nombre total d'enregistrements.