Каталог рос незаметно: сначала пара тысяч товаров с десятком свойств, потом сотни тысяч позиций и полсотни характеристик у каждой. И вот умный фильтр, который раньше отвечал мгновенно, задумывается на секунды, а страница категории еле собирается. Корень проблемы почти всегда один — модель хранения характеристик, выбранная в самом начале и не рассчитанная на такой объём.
В этой статье разберём три подхода к хранению характеристик товаров в контексте 1С-Битрикс: EAV, на котором построены инфоблоки, отдельные таблицы и Highload-блоки, а также хранение в JSON. Посмотрим, как каждый влияет на фильтр и скорость, и когда что применять. Если каталог уже тормозит, начать стоит с диагностики — это аудит и оптимизация 1С и связки сайта с учётной системой.
Коротко
- Инфоблоки Битрикс построены на EAV: гибко добавлять свойства, но тяжёлые запросы при выборках.
- Highload-блоки хранят данные в нормальных колонках и хорошо индексируются — для больших справочников.
- JSON уместен для редких описательных атрибутов, не участвующих в фильтрации.
- На большом каталоге ключ к скорости фильтра — фасетный индекс, то есть денормализация ради выборки.
Почему хранение характеристик — это про производительность
Характеристики товара кажутся простой вещью: цвет, размер, бренд, вес. Но именно от того, как они физически лежат в базе, зависит скорость двух самых нагруженных сценариев магазина — вывода каталога и работы умного фильтра. Одна и та же логическая структура «товар и его свойства» может быть реализована так, что фильтр летает, или так, что он падает под нагрузкой.
Проблема в конфликте требований. Бизнесу нужна гибкость: заводить новые свойства на лету, без участия разработчика. Базе данных для скорости нужна жёсткая структура: колонки с индексами, по которым быстро выбирать. Эти требования тянут в разные стороны, и каждая модель хранения — это компромисс между ними. Понимание компромисса и позволяет выбрать верно.
EAV: как устроены свойства инфоблоков
EAV (Entity-Attribute-Value) — модель, в которой характеристики хранятся не столбцами таблицы товаров, а отдельными строками вида «товар — свойство — значение». Именно на ней построены инфоблоки 1С-Битрикс: значения свойств лежат в служебных таблицах и связываются с элементом по идентификатору.
Сильная сторона EAV — гибкость. Новое свойство добавляется через интерфейс, без изменения схемы базы и без миграций: контент-менеджер заводит характеристику, и она сразу доступна. Для магазина, где ассортимент и его атрибуты постоянно меняются, это огромное удобство.
Плата — производительность выборок. Чтобы собрать товар со всеми свойствами или отфильтровать по нескольким характеристикам, нужны джойны по таблице значений: каждое свойство — это ещё одно соединение. На небольшом каталоге незаметно, на крупном — превращается в тяжёлые запросы. Поэтому Битрикс поверх EAV строит дополнительные оптимизации, о которых ниже.
Отдельные таблицы и Highload-блоки
Противоположность EAV — нормальная реляционная таблица, где каждая характеристика это отдельная колонка со своим индексом. Выборка и фильтрация по такой структуре максимально быстры: база делает то, для чего создана. Минус — жёсткость: чтобы добавить свойство, нужно менять схему.
В 1С-Битрикс этот подход воплощён в Highload-блоках. Это отдельные сущности, данные которых хранятся в собственной таблице с колоночной структурой и хорошо индексируются. Их применяют там, где EAV-свойства инфоблока начинают буксовать:
- Большие справочники. Бренды, цвета, размеры и другие списки, привязываемые к товарам, с большим числом значений.
- Данные с высокой нагрузкой на выборку. Характеристики, по которым часто идёт фильтрация на объёме в сотни тысяч и миллионы записей.
- Служебные и расчётные данные. То, что удобнее держать в быстрой колоночной структуре, а не в EAV.
Работать с Highload-блоками удобно через D7 ORM — про этот слой мы подробно писали в статье D7 ORM в Битрикс: типизированные сущности, связи и запросы делают код с большими справочниками поддерживаемым.
JSON: когда это оправдано
Третий подход — хранить набор характеристик в одном поле как JSON. Штатно Битрикс работает поверх MySQL, где нет полноценного JSONB как в PostgreSQL, но есть тип JSON и функции для работы с ним. Соблазн понятен: свалить все разнородные атрибуты в одно поле и не плодить свойства.
Однако JSON уместен в узком случае — для редких, описательных, разнородных атрибутов, которые не участвуют в фильтрации и сортировке. Например, технические подробности, которые показываются в карточке, но по ним никто не фильтрует. Для полей, по которым идёт фильтр, JSON — плохой выбор: индексировать и выбирать по вложенным значениям сложнее и медленнее, чем по обычным колонкам, а умный фильтр Битрикс с таким хранением штатно не работает.
Сравнение трёх подходов
Сведём подходы в таблицу по ключевым для магазина критериям.
| Критерий | EAV (свойства инфоблока) | Highload / таблицы | JSON-поле |
|---|---|---|---|
| Гибкость добавления | Высокая | Низкая (нужна миграция) | Высокая |
| Скорость фильтрации | Средняя (нужен фасет) | Высокая | Низкая |
| Индексация | Через фасетный индекс | Нативная по колонкам | Ограниченная |
| Объём данных | До крупного с оптимизацией | Миллионы записей | Небольшой |
| Интеграция с фильтром | Полная (штатно) | Через справочники/свойства | Нет |
| Роль в проекте | Основные свойства | Большие справочники | Описательные атрибуты |
Из таблицы виден главный вывод: не бывает «лучшего» подхода в вакууме. EAV выигрывает в гибкости, таблицы — в скорости, JSON — в простоте для несущественных данных. Реальные проекты комбинируют их.
Как модель влияет на умный фильтр
Умный фильтр (catalog.smart.filter) — самый чувствительный к модели хранения компонент. Он строит запросы по выбранным характеристикам, и на каждое свойство в EAV приходится дополнительное соединение с таблицей значений. Когда пользователь отмечает пять-шесть свойств на каталоге в сотни тысяч товаров, «наивный» запрос по EAV становится неприемлемо медленным.
Поэтому производительность фильтра определяется не только тем, много ли у вас свойств, но и тем, как они хранятся и индексируются. Для интенсивной фильтрации на большом каталоге EAV без дополнительной оптимизации не годится — нужен фасетный индекс. Для характеристик, вынесенных в Highload-блоки и справочники, выборка идёт быстрее за счёт нормальной индексации.
Фасетный индекс и денормализация
Чтобы примирить гибкость EAV со скоростью фильтра, Битрикс использует фасетную индексацию. Это предрассчитанная структура — по сути таблица соответствий «свойство-значение — товар», по которой умный фильтр выбирает подходящие позиции без тяжёлых джойнов по таблице значений.
По природе это денормализация: данные о свойствах дублируются в форме, удобной для фильтра, ради скорости выборки. Важные следствия:
- Свойства для фильтра нужно индексировать. В настройках инфоблока включается участие свойства в умном фильтре и его индексация.
- Индекс надо поддерживать. При массовом изменении товаров (особенно после обмена) фасет требует переиндексации, иначе фильтр покажет неактуальные данные.
- Не всё стоит индексировать. Индексируют только те свойства, по которым реально фильтруют, чтобы не раздувать структуру.
Фасетный индекс — стандартный и обязательный инструмент для больших каталогов. Без него любая красивая модель хранения упрётся в медленный фильтр.
Гибридная модель на практике
На реальных проектах побеждает не одна модель, а их осознанное сочетание. Типовое разделение выглядит так:
- Фильтруемые характеристики — свойства инфоблока с фасетом. Цвет, размер, бренд, диапазоны — то, по чему покупатель фильтрует, лежит в индексируемых свойствах.
- Большие справочники — Highload-блоки. Обширные списки значений и данные с высокой нагрузкой на выборку выносятся в отдельные таблицы.
- Описательные атрибуты — JSON или простые поля. То, что только показывается в карточке и не участвует в фильтре.
- Торговые предложения — под варианты. Свойства, различающие SKU (размер, цвет), ведутся в торговых предложениях.
Ключ — осознанность: каждая характеристика попадает туда, где её сильные стороны важнее слабых. Такое разделение проектируют заранее, а не выправляют потом, когда каталог уже вырос и фильтр встал.
Связь с обменом 1С по CommerceML
В магазине на Битрикс характеристики почти никогда не заводятся только руками — они приходят обменом с учётной системой по CommerceML и ложатся в свойства инфоблоков и торговых предложений. Поэтому модель хранения нельзя выбирать в отрыве от того, как данные выгружаются из 1С.
- Стабильные большие справочники. Если в 1С ведётся обширный устойчивый справочник, его удобно хранить как Highload-блок и синхронизировать.
- Динамичные свойства. Часто меняющиеся характеристики удобнее держать свойствами инфоблока с их гибкостью.
- Согласованность структуры. Структура свойств на сайте и в учётной системе должна совпадать, иначе обмен затирает или дублирует данные.
Ошибки обмена — отдельная больная тема: «плавающие» коды и рассинхрон структуры ломают и данные, и фильтр. Наведение порядка в этой связке — часть работ по автоматизации, в том числе автоматизации на 1С.
Как выбрать модель под проект
Практический алгоритм выбора для каждой характеристики:
- По ней фильтруют? Да — индексируемое свойство инфоблока с фасетом или Highload-блок. Нет — простое поле или JSON.
- Сколько значений в справочнике? Тысячи и больше с нагрузкой на выборку — Highload-блок.
- Как часто меняется структура? Часто — гибкость EAV. Стабильно и много данных — таблица.
- Откуда приходят данные? Согласуйте модель с выгрузкой из 1С по CommerceML.
- Каков объём каталога? Сотни тысяч позиций — обязательны фасетный индекс и вынос тяжёлого в Highload.
Если каталог планируется большим, архитектуру хранения закладывают на старте и проверяют на реалистичном объёме данных, а не на десятке тестовых товаров.
Частые ошибки
- Всё в свойствах инфоблока. Огромные справочники в EAV без Highload — фильтр тормозит на объёме.
- Фильтруемые данные в JSON. По ним невозможно быстро выбирать, умный фильтр их не видит.
- Не включён фасетный индекс. На большом каталоге фильтр по EAV работает на джойнах и падает под нагрузкой.
- Индекс не переиндексируют после обмена. Фильтр показывает устаревшие значения свойств.
- Индексируют всё подряд. Раздутый фасет по свойствам, по которым никто не фильтрует.
- Структура сайта и 1С расходятся. Обмен затирает или дублирует характеристики.
- Модель выбрана на десяти тестовых товарах. На реальном объёме всё тормозит.
Чек-лист и вывод
- Характеристики классифицированы. Понятно, что фильтруется, что только показывается, где большие справочники.
- Фильтруемые свойства индексируются. Включён фасетный индекс, лишнее не индексируется.
- Большие справочники в Highload. Объёмные данные вынесены из EAV.
- JSON — только для описательного. Никаких фильтруемых полей в JSON.
- Модель согласована с 1С. Структура совпадает с выгрузкой по CommerceML.
- Переиндексация настроена. Фасет обновляется после массовых изменений и обмена.
- Проверено на реальном объёме. Фильтр и каталог протестированы на боевом количестве товаров.
Хранение характеристик — это не абстрактная база данных, а фундамент скорости каталога и фильтра. EAV даёт гибкость, отдельные таблицы и Highload-блоки — скорость, JSON — простоту для несущественного. Ни один подход не универсален; сильные проекты комбинируют их осознанно и опираются на фасетный индекс там, где нужен быстрый фильтр.
Проектируйте модель под реальный объём и под то, как данные приходят из 1С, — и каталог останется быстрым, даже когда вырастет до сотен тысяч позиций с десятками характеристик у каждой.