Каталог в котором очень много данных может работать не достаточно быстро. Если не использовать готовые CMS, которые используют универсальные структуры данных, а хранить данные непосредственно в плоских таблицах, то можно получить достаточно неплохие результаты, но рано или поздно все равно наступает момент когда страница начинает тормозить из-за слишком долгих выборок.
Звучит логично, но я задался вопросом, а какую же именно скорость выборок ожидать клиенту при разных объемах данных. Сколько будет формироваться страница в каталоге на 5 позиций, сколько на 500, сколько на 5 000, и сколько на 1 000 000 записей? Допустим, потенциальный клиент хочет знать к чему ему готовится при работе с каталогом на 200 000 позиций, что ему ответить?
Чтобы получить точный ответ на этот вопрос, я собрал демо-стенд с тестовыми данными на PHP фреймворке CodeIgniter 3, он устарел много лет назад, но тем не менее имеет стабильные версии, совместимые с современными версиями PHP, и для этой задачи подошел идеально. Итого, в таблице 10 столбцов целого типа (int), в каждом из этих столбцов может находится число от 0 до 100. В таблице 1 000 000 (один миллион) строк. Каждая строка может быть отфильтрована по точному значению, или в диапазоне от и до, плюс есть сортировка в любом направлении по любому из полей. На странице выводится максимальное 10 элементов и есть переход между страницами. Подобная система имитирует работу фильтров в типовом каталоге.
Какие же результаты мы имеем?
- Загрузка первой страницы в каталоге: 0,02 секунды
- Загрузка последней страницы в каталоге: 0,2 секунды
- Загрузка 20 000 страницы в каталоге: 0.09 секунды (последняя страница в каталоге на 200 000 позиций)
При больших объемах данных производительность обратным образом зависит от количества фильтров которые мы применяем к выборке. Это значит, что если мы применяем 10 фильтров, то все работает очень быстро потому что базе данных приходится работать с меньшим объемом данных, чем с более простыми фильтрами, или вообще без них. Но главное на что надо обратить внимание, это то что проблемы с производительностью зависят не от количества фильтров, а от того какую страницу в выборке мы хотим открыть. И самое неприятное то что медленно работает запрос определения общего количества элементов под условия фильтра. Первая страница каталога будет открываться примерно также медленно как и последняя, если на первой странице мы будем получать общее количество элементов.
Нет никакого секретного рецепта волшебных запросов к БД от профессионалов SQL, чтобы ваш сайт полетел. Оптимизация происходит не на программном уровне, а на уровне разработки технического задания. Если ТЗ и макеты не учитывают особенности работы с большими данными, то программистам остается только вводить кеширование всего чего можно, там где можно, и даже там где нельзя.
Особенности формирования больших каталогов:
Не делать выводов больших каталогов с постраничной пагинацией, ваши пользователи не будут кликать назад/вперед по сотням и тысячам страниц. Скорее всего никто и никогда не будет смотреть данные дальше 100 страницы, а если кому-то нужно попасть в конец списка, то его нужно просто отсортировать в обратном порядке, и открыть первую страницу.
Ограничивать максимально возможную страницу которую пользователь может открыть. Если первый пункт не выполнен, и на сайте есть каталоги которые выводятся большими списками, то просто не позволять открывать дальние страницы. Пусть пользователи используют фильтры, чтобы найти нужные данные.
Не писать общее количество данных, вроде "найдено 100 элементов из 10 000", т.к. подобная строчка в 20 раз увеличивает время загрузки первой страницы каталога, она содержит целых два дополнительных тяжелых запроса.
Общее количество данных в каталоге уместно кешировать.
Не делать прямую ссылку на последнюю страницу в каталоге в пагинации. Если такая ссылка находится на каждой странице каталога, то независимо от того какая страница открыта, будет выполняться тяжелый запрос на выборку всех элементов. Я сделал отдельный эндпойнт для последней страницы и делаю ссылку на него, а он уже определяет последнюю страницу и делает переадресацию. Так тяжелый запрос выполняется один раз, только когда это действительно нужно.
С первого взгляда, может показаться что выполнение этих советов сильно ограничивает ваш сайт, но присмотритесь к другим крупным сайтам в сети. Когда последний раз вы видели пагинацию с более чем 1 000 страницами? А на всех ли сайтах написано сколько элементов найдено? А вы уверены, что ссылка на последнюю страницу каталога есть на всех сайтах которыми вы пользуетесь?
Обсудим как будем выводить данные, или будете дальше искать волшебную SQL пилюлю?
09.03.2026
Комментарии
- Нет комментариев.
