На каталоге в 500 товаров почти любая CMS работает нормально. На 30 000 SKU начинают проявляться проблемы, которые раньше не были видны: фильтры грузятся секундами, поиск выдаёт странные результаты, а часть страниц вообще не индексируется.
Большой каталог — это не только вопрос сервера. Это модель данных, индексы, кэш, пагинация, правила индексации и UX фильтров. Ниже — порядок, который помогает навести порядок без переписывания всего магазина.
Почему каталог начинает тормозить
Главная причина — количество вариантов комбинаций. Фильтры по цвету, размеру, бренду и характеристикам создают тысячи комбинаций URL и запросов. Если каждое сочетание считается на лету по всей таблице, база быстро упирается.
- Запросы без индексов по полям фильтров.
- N+1 при выводе характеристик и изображений.
- Подсчёт фасетов по всему каталогу на каждый запрос.
- Слишком большое число страниц пагинации.
- Кэш, который не учитывает комбинации фильтров.
- Поиск через LIKE по нескольким полям без индекса.
Модель данных и индексы
Перед оптимизацией запросов проверьте модель. Если характеристики хранятся в JSON и фильтруются через LIKE, никакие индексы не спасут. Для больших каталогов нужна нормальная структура: товар, вариант, значение характеристики и связь между ними.
- Отдельные таблицы для товаров, вариантов и значений характеристик.
- Индексы по полям, которые реально участвуют в фильтрах и сортировке.
- Короткие типы данных и стабильные идентификаторы.
- Денормализация самых частых фильтров, если она оправдана.
- Регулярное обслуживание таблиц и статистики.
Не добавляйте индекс на каждое поле «на всякий случай». Индексы замедляют запись и занимают место. Смотрите на реальные запросы и добавляйте то, что даёт эффект.
Фильтры: как не убить базу
Фасетные фильтры — самая дорогая часть каталога. Пользователь выбирает несколько значений, и система должна показать товары и посчитать, сколько их будет при добавлении ещё одного фильтра. Если считать это каждый раз заново, база будет постоянно загружена.
- Кэшируйте результаты популярных комбинаций фильтров.
- Считайте фасеты по индексированным полям, а не по всей таблице.
- Ограничивайте число одновременно выбранных фильтров.
- Не показывайте пустые комбинации, если это не нужно бизнесу.
- Проверяйте планы запросов на реальных объёмах.
Для очень больших каталогов иногда имеет смысл вынести поиск и фасеты в отдельный движок. Но это оправдано, когда обычная база уже не справляется, а не «на всякий случай» на старте.
Поиск: от LIKE до поискового движка
Поиск по названию и артикулу должен работать быстро и предсказуемо. LIKE с ведущим процентом почти всегда означает полное сканирование таблицы. Полнотекстовый индекс или отдельный поисковый движок решают эту проблему.
- Ищите по названию, артикулу и ключевым характеристикам.
- Поддерживайте опечатки и синонимы, если это важно аудитории.
- Сортируйте результаты по релевантности, а не только по цене.
- Логируйте запросы без результатов — это подсказки для ассортимента.
SEO для больших каталогов
Тысячи товаров создают тысячи страниц, и не все из них нужно индексировать. Если поисковик тратит краулинговый бюджет на пустые фильтры и дубли, важные категории индексируются медленнее.
- Канонические URL для категорий и товаров.
- Canonical или noindex для пустых и мусорных комбинаций фильтров.
- Короткая пагинация без бесконечных duplicate-страниц.
- Sitemap с приоритетными категориями и товарами.
- Уникальные заголовки и описания для ключевых категорий.
- Внутренние ссылки из категорий на важные подборки.
Не пытайтесь индексировать каждую комбинацию фильтров. Лучше сделать несколько сильных посадочных страниц под важные запросы, чем тысячи тонких страниц без контента.
Кэш и фасеты
Кэш помогает, если у него понятные ключи и инвалидация. Для каталога ключ должен учитывать категорию, фильтры, сортировку и страницу. Иначе пользователь увидит результаты чужого запроса.
Прогревайте кэш популярных категорий после выгрузки и сбрасывайте его при изменении товаров, цен и остатков. Это особенно важно перед распродажей.
Админка и выгрузка
Каталог на 30 000 SKU невозможно вести вручную по одному товару. Нужны массовые операции, импорт, понятные статусы выгрузки и возможность отката. Если менеджеры обходят админку через Excel, проблема не только в интерфейсе.
- Массовое изменение цен и характеристик.
- Импорт с валидацией и отчётом об ошибках.
- Очередь выгрузки и статус обработки.
- История изменений по критичным полям.
Чек-лист большого каталога
Пагинация и бесконечная лента
Большой каталог почти всегда означает много страниц. Если пагинация устроена плохо, пользователь теряется, а поисковик тратит краулинговый бюджет на дубли. Отдельно это бьёт по мобильным, где бесконечная лента быстро съедает память.
- Ограничьте глубину пагинации и предложите фильтры.
- Не делайте бесконечную ленту единственным способом навигации.
- Следите за canonical и параметрами URL.
- Проверяйте, что возврат назад сохраняет позицию.
Для SEO важнее несколько сильных категорий и подборок, чем бесконечная цепочка страниц с одинаковыми товарами. Для UX важнее быстрый доступ к нужному фильтру, чем десятки экранов прокрутки.
Карточка товара и изображения
На карточке каталог встречается с конверсией. Если страница грузит десять изображений в полном размере и десятки характеристик, покупатель уходит до того, как увидит цену и кнопку.
- Главное изображение — сжатое, с правильными размерами.
- Остальные фото — по мере необходимости, а не все сразу.
- Характеристики не должны превращаться в простыню.
- Кнопка покупки видна без долгой прокрутки.
- Похожие товары не блокируют основной контент.
Типичные ошибки
- Индексировать все комбинации фильтров без разбора.
- Кэшировать каталог без учёта фильтров и сортировки.
- Пытаться решить поиск через LIKE на больших таблицах.
- Выводить все характеристики и изображения сразу.
- Не проверять каталог на мобильном и медленной сети.
Большой каталог требует дисциплины, а не героических оптимизаций в момент падения. Если модель данных, индексы и кэш в порядке, каталог масштабируется предсказуемо.
Кэш и инвалидация
Каталог хорошо кэшируется, но плохо переносит устаревшие данные. Ключ кэша должен учитывать категорию, фильтры, сортировку и страницу, а сброс — происходить при изменении товара, цены или остатка.
- Отдельные ключи для разных комбинаций фильтров.
- Сброс при изменении товара и категории.
- Прогрев популярных страниц после выгрузки.
- Запрет кэшировать персональные страницы.
Когда нужен отдельный поисковый движок
Отдельный движок добавляет инфраструктуру и сложность. Он оправдан, когда нужен сложный поиск, морфология, синонимы, высокая скорость фасетов и обычная база уже не справляется.
- Поиск с опечатками и синонимами.
- Быстрые фасеты на десятках тысяч товаров.
- Ранжирование и персонализация выдачи.
- Отдельное масштабирование поиска.
Начинать с движка стоит только после того, как проверены модель данных, индексы и кэш. Иначе вы добавите сложности, но не уберёте причину медленности.
Метрики большого каталога
Оценивайте каталог не по одной цифре, а по набору показателей. Быстрый ответ сервера ещё не значит, что покупатель быстро находит товар.
- Время ответа категории и поиска.
- Доля запросов без результатов.
- Глубина просмотра и переходы в карточку.
- Конверсия из категории в корзину.
- Количество ошибок и таймаутов.
Смотрите метрики по сегментам: мобильные, новые пользователи, поисковый трафик. Средние значения по сайту часто скрывают проблему в конкретном сценарии.
Не забывайте про контент. Пустые описания и одинаковые заголовки у тысяч товаров создают тонкие страницы, которые плохо ранжируются. Даже шаблонные, но осмысленные тексты и характеристики помогают поиску и покупателю.
Если каталог растёт, закладывайте запас по индексам и кэшу заранее. Переписывать модель данных на 50 000 товарах дороже, чем добавить нужные поля и связи на этапе проектирования.
Посмотрим модель данных, фильтры, поиск и индексацию. Предложим план без переписывания всего магазина.
Обсудить каталог →