Показать много данных с помощью доктрины ORM Symfony

Я пытаюсь провести проверку заряда с помощью веб-приложения Symfony. У меня есть сущность с 13 полями, включая 1 первичный ключ и 7 внешних ключей. Я ввел 40 тысяч данных.

Мой контроллер использует findAll() и KNP Paginator с максимум 10 строками на странице. Отображение страницы занимает много времени (от 15 до 30 секунд), вот результат моего профилировщика:

Показатели эффективности :

  • общее время выполнения: 29680 мс
  • Пиковое использование памяти: 154 МБ

Я пробовал без родственных ключей, это лучше, но пока неприемлемо. Показатели эффективности :

  • общее время выполнения: 5600 мс
  • Пиковое использование памяти: 88 МБ

Что вы порекомендуете для отображения большого количества данных с нумерацией страниц? Спасибо за помощь.

Хорошего дня.

<?php

namespace App\Controller\Admin;

use App\Repository\ChargeRepository;
use Knp\Component\Pager\PaginatorInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;

class ChargeController extends AbstractController
{
    #[Route('/admin/charge', name: 'app_admin_charge')]
    public function index(ChargeRepository $repository, PaginatorInterface $paginator, Request $request): Response
    {
        $data = $paginator->paginate(
            $repository->findAll(),
            $request->query->getInt('page', 1),
            10
        );
       // dd($myTickets);
        return $this->render('admin/charge/index.html.twig', [
            'data' => $data
        ]);
    }
}

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
0
70
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Согласно их документации, вы должны разбивать на страницы сам построитель запросов, а не результат findAll. Когда вы используете findAll, вы загружаете все объекты из базы данных и увлажняете их, это занимает много времени для 40 тысяч строк.

Что-то вроде этого уже могло помочь:

$data = $paginator->paginate(
  $repository->createQueryBuilder('charge'),
  $request->query->getInt('page', 1),
  10
);

Используя этот код, пагинатор добавляет необходимое ограничение на нумерацию страниц к самому запросу базы данных, так что загружаются только те элементы, которые также отображаются на текущей странице.

Святое решение, спасибо вам огромное. Я пробовал с данными 80 тыс., страница загружалась за 200 мс :о. Спасибо за объяснение, вы нашли эту информацию в документации по доктрине или в документе KNP?

Gigi_IT 27.02.2024 14:17

Часть документации, часть чтения вашего кода

Nico Haase 27.02.2024 14:36

Выбор всех данных с помощью метода findAll() не является хорошей практикой, если у вас большое количество данных. Попробуйте использовать пользовательскую нумерацию страниц с помощью firstResult и maxResults. Вот пример:

/**
 * @param int $page
 * @param int $maxResults
 * @return Charge[]
 */
public function getPaginated(int $page = 1, int $maxResults = 50): array
{
    return $this->createQueryBuilder('c') // add where clauses if you need
        ->setFirstResult(($page - 1) * $maxResults)
        ->setMaxResults($maxResults)
        ->getQuery()
        ->getResult();
}

Другие вопросы по теме