Měli byste svůj dotaz zjednodušit. To by zkrátilo dobu provádění. Nemohu otestovat váš dotaz, ale zde je několik ukazatelů:
- při provádění count() neprovádějte řazení
- můžete třídit podle orderBy('p.id', 'DESC') , použije se index
- místo leftJoin() můžete použít join() pokud u spojené tabulky vždy existuje alespoň jeden záznam. Jinak je tento záznam přeskočen.
- KNP/Paginator používá DISTINCT() ke čtení pouze odlišných záznamů, ale to by mohlo vést k použití tabulky tmp disku
- $query->getArrayResult() používá režim skrývání pole, který vrací vícerozměrné pole a je mnohem rychlejší než hydratace objektů pro velkou sadu výsledků
- můžete použít částečné select('částečné p.{id, další použitá pole}') , tímto způsobem byste načetli pouze potřebná pole, možná byste přeskočili nepotřebné vztahy při použití hydratace objektů
- zkontrolujte SF profiler EXPLAIN u daného dotazu v sekci doktríny, možná nejsou použity indexy
- vrací p.hashtags a p.likes pouze jeden řádek nebo je oneToMany, čímž se výsledek násobí
- možná nějaké změny designu příspěvků, které by odstranily některá spojení:
- mají pole p.hashtags definované jako @ORM\Column(type="array") a mají uložené řetězcové hodnoty značek. Později možná pomocí fulltextového vyhledávání na serializovaném poli.
- mají pole p.likesCount definované jako @ORM\Column(type="integer") který by měl počet lajků
Používám KnpLabs/KnpPaginatorBundle a může mít také problémy s rychlostí pro složité dotazy.
Obvykle použití LIMIT x,z je pro DB pomalé, protože běží COUNT na celé datové sadě. Pokud se indexy nepoužívají, je to bolestně pomalé.
Mohli byste použít jiný přístup a provést nějaké vlastní stránkování posunutím ID, ale to by váš přístup zkomplikovalo. Použil jsem to s velkými datovými sadami, jako jsou tabulky SYSLOG. Ale ztratíte funkci třídění a celkového počtu záznamů.