Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Doctrine Paginator wählt ganze Tabelle aus (sehr langsam)?

Sie sollten Ihre Abfrage vereinfachen. Das würde einige Ausführungszeit sparen. Ich kann Ihre Abfrage nicht testen, aber hier sind ein paar Hinweise:

  • nicht sortieren, während count() ausgeführt wird
  • Sie könnten nach orderBy('p.id', 'DESC') sortieren , Index würde verwendet werden
  • statt leftJoin() Sie könnten join() verwenden wenn in der verknüpften Tabelle immer mindestens ein Datensatz vorhanden ist. Andernfalls wird dieser Datensatz übersprungen.
  • KNP/Paginator verwendet DISTINCT(), um nur unterschiedliche Datensätze zu lesen, aber das könnte dazu führen, dass die tmp-Tabelle der Festplatte verwendet wird
  • $query->getArrayResult() verwendet den Array-Hidration-Modus, der mehrdimensionale Arrays zurückgibt und viel schneller ist als Objekt-Hidration für große Ergebnismengen
  • Sie könnten teilweise select('partial p.{id, other used fields}') verwenden , auf diese Weise würden Sie nur benötigte Felder laden und möglicherweise nicht benötigte Beziehungen überspringen, wenn Sie die Objekthydratation verwenden
  • überprüfen Sie den SF-Profiler EXPLAIN für eine bestimmte Abfrage im Doktrinenabschnitt, möglicherweise werden Indizes nicht verwendet
  • gibt p.hashtags und p.likes nur eine Zeile zurück oder ist oneToMany, was das Ergebnis multipliziert
  • vielleicht einige Posts Designänderungen, die einige Joins entfernen würden:
    • haben das p.hashtags-Feld definiert als @ORM\Column(type="array") und haben gespeicherte Zeichenfolgenwerte von Tags. Später vielleicht mit Volltextsuche auf serialisiertem Array.
    • haben das p.likesCount-Feld definiert als @ORM\Column(type="integer") was viele Likes haben würde

Ich verwende KnpLabs/KnpPaginatorBundle und kann auch Geschwindigkeitsprobleme bei komplexen Abfragen haben.

Normalerweise ist die Verwendung von LIMIT x, z für DB langsam, da es COUNT für den gesamten Datensatz ausführt. Wenn Indizes nicht verwendet werden, ist es quälend langsam.

Sie könnten einen anderen Ansatz verwenden und eine benutzerdefinierte Paginierung durch ID-Fortschritt vornehmen, aber das würde Ihren Ansatz erschweren. Ich habe dies mit großen Datensätzen wie SYSLOG-Tabellen verwendet. Aber Sie verlieren die Funktionen zum Sortieren und zur Gesamtzahl der Datensätze.