Deberías simplificar tu consulta. Eso reduciría un poco el tiempo de ejecución. No puedo probar su consulta, pero aquí hay algunos consejos:
- no ordene mientras ejecuta count()
- podría ordenar por orderBy('p.id', 'DESC') , se usaría el índice
- en lugar de leftJoin() podrías usar join() si siempre existe al menos un registro en la tabla unida. De lo contrario, ese registro se omite.
- KNP/Paginator usa DISTINCT() para leer solo registros distintos, pero eso podría llevar a usar la tabla disk tmp
- $query->getArrayResult() usa el modo de hidratación de matrices, que devuelve una matriz multidimensional y es mucho más rápido que la hidratación de objetos para un gran conjunto de resultados
- podría usar parcial select('parcial p.{id, otros campos usados}') , de esta manera solo cargaría los campos necesarios, tal vez omita las relaciones innecesarias al usar la hidratación de objetos
- verifique EXPLAIN del perfilador de SF en una consulta dada en la sección de doctrina, tal vez no se usen índices
- ¿p.hashtags y p.likes devuelven solo una fila o es oneToMany, que multiplica el resultado
- tal vez algunos cambios en el diseño de las publicaciones, que eliminarían algunas uniones:
- tener el campo p.hashtags definido como @ORM\Column(type="array") y han almacenado valores de cadena de etiquetas. Más tarde, tal vez usando la búsqueda de texto completo en una matriz serializada.
- tener el campo p.likesCount definido como @ORM\Column(type="integer") que tendría un conteo de me gusta
Uso KnpLabs/KnpPaginatorBundle y también puede tener problemas de velocidad para consultas complejas.
Por lo general, usar LIMIT x,z es lento para DB, porque ejecuta COUNT en todo el conjunto de datos. Si no se utilizan índices, es dolorosamente lento.
Podría usar un enfoque diferente y hacer una paginación personalizada mediante el avance de ID, pero eso complicaría su enfoque. Lo he usado con grandes conjuntos de datos como tablas SYSLOG. Pero pierde la funcionalidad de clasificación y recuento total de registros.