Du bör förenkla din fråga. Det skulle raka av en del avrättningstid. Jag kan inte testa din fråga men här är några tips:
- Sortera inte medan du kör count()
- du kan sortera efter orderBy('p.id', 'DESC') , index skulle användas
- istället för leftJoin() du kan använda join() om det alltid finns minst en post vid sammanfogad tabell. Annars hoppas posten över.
- KNP/Paginator använder DISTINCT() för att endast läsa distinkta poster, men det kan leda till att disk-tmp-tabellen används
- $query->getArrayResult() använder array hidration mode, som returnerar multidimension array och det är mycket snabbare än objekt hidration för stora resultat set
- du kan använda partial select('partial p.{id, other used fields}') , på det här sättet skulle du bara ladda de fält som behövs, kanske hoppa över onödiga relationer när du använder objekthydrering
- kolla SF profiler EXPLAIN på en given fråga under doktrinsektionen, kanske index inte används
- returerar p.hashtags och p.likes bara en rad eller är oneToMany, vilket multiplicerar resultatet
- kanske några inläggsdesignändringar, som skulle ta bort några anslutningar:
- har p.hashtags-fältet definierat som @ORM\Column(type="array") och har lagrade strängvärden för taggar. Senare kanske du använder fulltextsökning på serialiserad array.
- har p.likesCount-fältet definierat som @ORM\Column(type="integer") som skulle ha antal likes
Jag använder KnpLabs/KnpPaginatorBundle och kan även ha hastighetsproblem för komplexa frågor.
Användning av LIMIT x,z är vanligtvis långsam för DB, eftersom den kör COUNT på hela datamängden. Om index inte används är det smärtsamt långsamt.
Du kan använda ett annat tillvägagångssätt och göra lite anpassad paginering genom att flytta fram ID, men det skulle komplicera ditt tillvägagångssätt. Jag har använt detta med stora datamängder som SYSLOG-tabeller. Men du tappar sortering och totalt antal poster.