Магазин на десять тысяч товаров: что ломается на объёме
Магазин с большим каталогом тормозит почти всегда по одной причине: страница просит у базы данных больше, чем ей нужно, и делает это в цикле. Мощность сервера тут вторична. Ниже — восемь конкретных ошибок из практики, каждая с описанием, последствием и правильным вариантом.
Порядок примерно соответствует частоте: первые три встречаются почти в каждом медленном магазине.
Ошибка 1. Запрос к базе внутри цикла по товарам
В чём. Страница получает список из тридцати товаров, а потом для каждого отдельно спрашивает у базы цену, остаток, картинку и категорию. Вместо одного запроса получается сто двадцать.
Чем оборачивается. На тридцати товарах разницы не видно, на витрине с фильтрами и подгрузкой она превращается в секунды ожидания. При этом сервер не загружен — он просто ждёт базу.
Как правильно. Все связанные данные забираются вместе со списком, одним-двумя запросами. Проверить легко: включите журнал запросов и откройте страницу категории. Если число запросов растёт вместе с числом товаров на странице — ошибка ваша.
Ошибка 2. Фильтры без индексов
В чём. Свойства товаров лежат в общей таблице «свойство — значение», а индексов на ней нет. Каждый фильтр заставляет базу перебирать таблицу целиком.
Чем оборачивается. Открытие категории — полсекунды, применение двух фильтров — восемь секунд. Люди уходят на третьей.
Как правильно. Индексы на столбцы, по которым идёт фильтрация, и отдельная таблица предрассчитанных значений для тяжёлых свойств. Заодно проверьте, что фильтр не выбирает сначала все подходящие товары, а потом отбрасывает лишние в коде.
Ошибка 3. Картинки в исходном размере
В чём. Владелец загружает фотографии прямо с камеры, по три-пять мегабайт, а витрина показывает их через уменьшение средствами браузера.
Чем оборачивается. Категория с тридцатью карточками весит сотню мегабайт. На телефоне через мобильный интернет она не открывается вовсе.
Как правильно. При загрузке из каждой фотографии делается несколько размеров: миниатюра для списка, средний для карточки, оригинал для увеличения. Формат — современный, с запасным вариантом. Делается один раз при загрузке, а не при каждом показе.
Ошибка 4. Импорт, который блокирует магазин
В чём. Обновление цен и остатков идёт одним большим куском в том же процессе, что и витрина. Пока десять тысяч строк перезаписываются, база занята.
Чем оборачивается. Каждое утро магазин на десять минут становится недоступным, и это списывают на хостинг.
Как правильно. Импорт разбивается на пакеты по несколько сотен строк и идёт в фоновой очереди. Обновляются только изменившиеся позиции, а не весь каталог целиком. В админке видно, сколько строк обработано и на какой позиции остановились при сбое.
В магазине «Жук и Плут» импорт с Wildberries сделан отдельной вкладкой: владелица запускает его сама, видит ход выполнения и список несовпадений. До этого триста позиций заводились руками и на это уходил вечер — при десяти тысячах такой подход не масштабируется вовсе.
Ошибка 5. Пагинация со сдвигом на конце каталога
В чём. Страницы каталога листаются через «пропустить N записей». На двадцатой странице база честно отбрасывает первые пятьсот строк, на трёхсотой — семь тысяч.
Чем оборачивается. Начало каталога быстрое, конец — медленный. Поисковый робот обходит каталог целиком и упирается именно в хвост, из-за чего часть товаров попадает в индекс с опозданием.
Как правильно. Листание по ключу последней показанной записи вместо сдвига. Для покупателя это выглядит так же, для базы — совсем иначе.
Ошибка 6. Счётчики, которые считаются на лету
В чём. Рядом с каждым фильтром показано число подходящих товаров, и оно вычисляется при каждом открытии страницы для каждого значения каждого свойства.
Чем оборачивается. Один заход в категорию порождает десятки тяжёлых запросов, причём результат у всех посетителей одинаковый.
Как правильно. Счётчики пересчитываются по расписанию или при изменении каталога и хранятся готовыми. Если точность до секунды не нужна — а она почти никогда не нужна, — это самая дешёвая оптимизация из возможных.
Ошибка 7. Админка, которая грузит весь каталог
В чём. Список товаров в админке открывается без разбивки на страницы, с картинками и всеми свойствами. Разработчик проверял его на сотне позиций.
Чем оборачивается. Владелец не может открыть свой каталог и работает через выгрузку в таблицу, а магазин теряет смысл управляемости.
Как правильно. Разбивка на страницы, поиск по артикулу и названию, фильтр по категории и статусу, массовые действия для выбранных строк. Проверяется на реальном объёме, а не на тестовых данных.
Ошибка 8. Поиск по подстроке
В чём. Поиск по каталогу устроен как перебор названий: ищем вхождение того, что ввёл покупатель. Индекс тут не работает, база просматривает все строки.
Чем оборачивается. Двойной удар. Поиск медленный, и он ничего не находит при опечатке, при другом порядке слов и при вводе артикула с пробелом.
Как правильно. Сначала полнотекстовый поиск средствами базы данных — этого хватает большинству магазинов. Дальше, если ассортимент сложный и покупатель не знает точных названий, подключают отдельный поисковый движок с учётом опечаток и синонимов.
На платформе Papa BU поиск сделан векторным, потому что там ищут не по названию, а по смыслу объявления. Обычному магазину такое не нужно, но признак, что пора думать в эту сторону, простой: покупатели пишут в поддержку «у вас нет такого товара», а товар есть.
Как проверить свой магазин за полчаса
По порядку, без инструментов сложнее браузера.
- Откройте категорию с наибольшим числом товаров и засеките время до появления карточек.
- Примените два фильтра подряд и засеките снова.
- Откройте предпоследнюю страницу каталога.
- Посмотрите вес самой большой картинки на странице категории.
- Откройте список товаров в админке и попробуйте найти позицию по артикулу.
- Запустите импорт и в это же время откройте витрину с телефона.
Если хотя бы два пункта дают заметную задержку, дело не в хостинге.
Когда объём не проблема
Каталог в десять тысяч позиций сам по себе не тяжёлый. Тяжёлым его делают фильтры, поиск и обновления. Магазин с большим числом простых товаров, где фильтр один и импорт раз в неделю, спокойно живёт на скромном сервере.
И обратный случай: если у вас двести товаров и всё тормозит, объём точно ни при чём — ищите ошибку первую из списка.
Коротко
Большой каталог ломается на восьми вещах: запросы в цикле, фильтры без индексов, необработанные картинки, блокирующий импорт, листание сдвигом, счётчики на лету, админка без разбивки на страницы и поиск перебором. Все восемь чинятся кодом, а не мощностью сервера. Проверка занимает полчаса и начинается с самой большой категории и двух применённых фильтров.
Первый разговор — разбор задачи: нужна ли вам система или хватит одной страницы. Без обязательств и без счёта.
Частые вопросы
С какого числа товаров начинаются проблемы?
Не с числа товаров, а с числа сочетаний. Тысяча позиций с пятнадцатью фильтруемыми свойствами тормозит сильнее, чем десять тысяч позиций с тремя. Первые признаки обычно появляются в районе двух-трёх тысяч карточек, если о нагрузке заранее не думали.
Поможет ли просто взять сервер помощнее?
Ненадолго. Более мощный сервер маскирует неверные запросы к базе, но каталог растёт быстрее, чем вы будете доплачивать за железо. Сначала разбирают запросы и индексы, и только потом, если упёрлись, увеличивают мощность.
Нужен ли отдельный поисковый движок?
Нужен, когда поиск по названию перестаёт находить нужное: пользователи пишут с опечатками, синонимами, артикулами. До этого момента хватает поиска средствами базы данных. Отдельный движок — это ещё одна система, которую надо обновлять и синхронизировать, и без причины его подключать не стоит.
Те, что не помогают, мы переписываем — по этой кнопке и решаем, какие именно.
Ещё по теме
Справка о составе чека, разграничении зон ответственности между сайтом, кассой и бухгалтерией и порядке проверки перед запуском.
тем, кто заказывает «Жук и Плут»: детский бренд ушёл с маркетплейсов на свой сайтИстория магазина детских товаров — что мы построили, что пошло не так и почему бренд встал первым в Яндексе на третий день.
тем, кто заказывает «С этим покупают»: где ставить блоки допродажКарта мест на сайте, где допродажа работает, и что показывать в каждом — от карточки товара до письма после доставки.
тем, кто заказывает