Du bør forenkle din forespørgsel. Det ville barbere noget udførelsestid af. Jeg kan ikke teste din forespørgsel, men her er et par tips:
- undlad at sortere, mens du udfører count()
- du kan sortere efter orderBy('p.id', 'DESC') , ville indeks blive brugt
- i stedet for leftJoin() du kan bruge join() hvis der altid findes mindst én post ved sammenføjet tabel. Ellers springes posten over.
- KNP/Paginator bruger DISTINCT() til kun at læse distinkte poster, men det kan føre til brug af disk tmp-tabel
- $query->getArrayResult() bruger array hidration mode, som returnerer multidimension array, og det er meget hurtigere end objekt hidration for store resultatsæt
- du kan bruge partial select('partial p.{id, other used fields}') , på denne måde vil du kun indlæse nødvendige felter, måske springe overflødige relationer over, når du bruger objekthydrering
- tjek SF profiler EXPLAIN på en given forespørgsel under doktrinsektionen, måske bruges indekser ikke
- returnerer p.hashtags og p.likes kun én række eller er oneToMany, hvilket multiplicerer resultatet
- måske nogle ændringer i Posts-designet, der ville fjerne nogle joinforbindelser:
- har p.hashtags-feltet defineret som @ORM\Column(type="array") og har gemt strengværdier af tags. Senere måske ved at bruge fuldtekstsøgning på serialiseret array.
- har p.likesCount-feltet defineret som @ORM\Column(type="integer") som ville have antal likes
Jeg bruger KnpLabs/KnpPaginatorBundle og kan også have hastighedsproblemer til komplekse forespørgsler.
Normalt er brug af LIMIT x,z langsom for DB, fordi det kører COUNT på hele datasættet. Hvis indekser ikke bruges, er det smerteligt langsomt.
Du kunne bruge en anden tilgang og lave noget tilpasset paginering ved at fremføre ID, men det ville komplicere din tilgang. Jeg har brugt dette med store datasæt som SYSLOG-tabeller. Men du mister sorterings- og totaloptællingsfunktionalitet.