Когда дело доходит до веб-приложений, время загрузки имеет важное значение, и вы не хотите, чтобы какая-либо из ваших страниц занимала более 3-5 секунд. У меня была одна из основных разбитых на страницы сеток, загружавшаяся за 30 секунд.
Мне нужно было что-то с этим делать.
Я вошел в эту сетку с включенным профилировщиком * и начал проверять время загрузки каждого запроса, происходящего с базой данных. Проблема заключалась не в извлечении записей, а в том, что запрос подсчета
Библиотека *, которую я использовал для разбивки на страницы, требует адаптера ORM, который по умолчанию использует OutputWalkers для получения количества записей.
Это выглядит примерно так:
SELECT
COUNT(*) AS dctrn_count
FROM
(
SELECT
DISTINCT id_0
FROM
(
SELECT
m0_.id AS id_0,
...
FROM
table_name m0_
) dctrn_result
) dctrn_table
А когда количество записей увеличивается, сложность этого запроса возрастает экспоненциально.
Очевидно, что если вам нужно подсчитать количество записей, вы можете использовать гораздо более простой запрос для подсчета.
Я просмотрел его и обнаружил, что для запуска экземпляра этой библиотеки вы передаете интерфейс адаптера (Doctrine ORM Adapter), и когда вы создаете новый экземпляр этого адаптера, вы можете указать, хотите ли вы использовать выходные обходчики или нет, и я попробовал и бум, запрос снизился до миллисекунд, и в результате страница теперь загружается менее чем за секунду.
Теперь запрос выглядит как ваш обычный счетчик:
SELECT count(DISTINCT id) FROM table_name WHERE condition = value
Конечно, при изменении такой вещи мне нужно было убедиться, что это изменение не повлияет ни на что в сетке или не повредит счет, и после исследования выяснилось, что этот обходчик вывода используется, чтобы убедиться, что запрос счетчика всегда будет работать даже при наличии группы by.
И в моем случае это был простой выбор для одной таблицы без какой-либо группы, поэтому для меня это было идеальное рабочее решение.
Вывод: когда что-то занимает больше времени, чем должно, знайте, что что-то не так, и примите меры.