Você deve simplificar sua consulta. Isso reduziria algum tempo de execução. Não posso testar sua consulta, mas aqui estão algumas dicas:
- não classifique ao executar count()
- você pode classificar por orderBy('p.id', 'DESC') , o índice seria usado
- em vez de leftJoin() você pode usar join() se pelo menos um registro sempre existir na tabela unida. Caso contrário, esse registro será ignorado.
- KNP/Paginator usa DISTINCT() para ler apenas registros distintos, mas isso pode levar ao uso da tabela tmp do disco
- $query->getArrayResult() usa o modo de hidratação de array, que retorna array multidimensional e é muito mais rápido que a hidratação de objetos para um grande conjunto de resultados
- você pode usar select('partial p.{id, other used fields}') parcial , desta forma você carregaria apenas os campos necessários, talvez pule relações não necessárias ao usar hidratação de objetos
- verifique o SF profiler EXPLAIN em uma determinada consulta na seção de doutrina, talvez os índices não sejam usados
- p.hashtags e p.likes retornam apenas uma linha ou é oneToMany, que multiplica o resultado
- talvez algumas mudanças no design das postagens, que removeriam algumas junções:
- ter o campo p.hashtags definido como @ORM\Column(type="array") e armazenaram valores de string de tags. Mais tarde, talvez usando pesquisa de texto completo em array serializado.
- ter o campo p.likesCount definido como @ORM\Column(type="integer") que teria contagem de curtidas
Eu uso KnpLabs/KnpPaginatorBundle e também pode ter problemas de velocidade para consultas complexas.
Normalmente, usar LIMIT x,z é lento para DB, porque executa COUNT em todo o conjunto de dados. Se os índices não são usados, é dolorosamente lento.
Você pode usar uma abordagem diferente e fazer alguma paginação personalizada por avanço de ID, mas isso complicaria sua abordagem. Eu usei isso com grandes conjuntos de dados, como tabelas SYSLOG. Mas você perde a funcionalidade de classificação e contagem total de registros.