Гайд 1С: Оптимизация работы с большими двоичными данными (ХранилищеЗначения)
- Раздувание таблиц баз данных до сотен гигабайт за счет колонок типа
IMAGE/VARBINARY(MAX)/BYTEA. - Резкое замедление динамических списков и форм справочников при открытии.
- Ошибки нехватки оперативной памяти на сервере 1С при считывании объектов в память целиком.
- Высокая фрагментация LOB-страниц на уровне СУБД.
1. Архитектурное разделение реквизитов
Никогда не помещайте реквизиты с типом ХранилищеЗначения непосредственно в шапку часто читаемых справочников или документов. При обращении через ПолучитьОбъект() СУБД вычитывает все LOB-поля в память, даже если они не требуются.
- Выносите двоичные данные в подчиненный регистр сведений (1:1) или специализированный справочник присоединенных файлов.
- Устанавливайте для реквизита флаг
Хранить сжатыми (Сжатие: Zip).
2. Оптимизация кода чтения двоичных данных в 1С
// НЕПРАВИЛЬНО: Вычитывает весь объект с BLOB-полями
ОбъектНоменклатуры = СсылкаНаНоменклатуру.ПолучитьОбъект();
Картинка = ОбъектНоменклатуры.ФайлКартинки.Получить();
// ПРАВИЛЬНО: Точечное чтение только ХранилищаЗначения через запрос
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Файлы.ДанныеФайла КАК Данные
|ИЗ
| РегистрСведений.ДвоичныеДанныеФайлов КАК Файлы
|ГДЕ
| Файлы.Файл = &СсылкаНаФайл";
Запрос.УстановитьПараметр("СсылкаНаФайл", СсылкаНаФайл);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
ДвоичныеДанные = Выборка.Данные.Получить();
КонецЕсли;3. Использование потокового чтения в платформе 8.3
Для файлов большого размера используйте потоки вместо загрузки всего массива байт в переменную:
Поток = Выборка.Данные.ОткрытьПотокДляЧтения();
// Потоковая обработка или передача клиенту без аллокации RAM в rphost Частые вопросы (FAQ)
Почему чтение ХранилищаЗначения замедляет работу СУБД?
Данные BLOB (LOB) хранятся в отдельных цепочках страниц за пределами стандартной 8 КБ страницы данных строки. Их чтение требует дополнительных случайных дисковых I/O операций и забивает буферный кэш СУБД неструктурированными данными.
Сжимает ли 1С данные при сохранении в ХранилищеЗначения по умолчанию?
При создании объекта ХранилищеЗначения конструктор принимает второй параметр: Новый ХранилищеЗначения(Данные, Новый СжатиеДанных(9)). По умолчанию сжатие отключено или минимально, если не задано явно.
Как обнаружить самые «раздутые» таблицы с ХранилищемЗначения в базе?
В MS SQL выполните стандартный отчет 'Disk Usage by Top Tables' (смотрите колонку Data/LOB Space). В PostgreSQL используйте запрос с pg_total_relation_size() и pg_relation_size() для TOAST-таблиц.
Помогает ли дефрагментация индекса для LOB-данных?
Нет. Стандартный REBUILD/REORGANIZE индекса часто не затрагивает LOB-страницы в старых версиях СУБД. Требуется полный REINDEX / VACUUM FULL таблицы.