новое событие
Информационный поток
Задания вакансии материалы разработки сообщения форума

Опасность в реквизите с типом "ХранилищеЗначения"

  • Добавить свою публикацию
  • для этого требуется регистрация

Ситуация

У нас есть справочник "Товры", в реквизите "Данные" которого сохраняется информация в виде двоичных данных. Сам реквизит имеет тип значения "ХранилищеЗначения". На следующем скриншоте представлена стркутура метаданных справочника.

 Изображение

 

Для прикрепления произвольного файла с диска в форме элемента реализована команда "ПрикрепитьФайл". Ее программный код представлен на следующем листинге:

 &НаКлиенте
Процедура ПрикрепитьФайл(Команда) // Обработчик команды на клиенте. Выбор файла
	// Диалог выбора файла с диска
	Режим = РежимДиалогаВыбораФайла.Открытие;
	ДиалогОткрытияФайла = Новый ДиалогВыбораФайла(Режим);
	ДиалогОткрытияФайла.ПолноеИмяФайла = "";
	ДиалогОткрытияФайла.МножественныйВыбор = Ложь;
	ДиалогОткрытияФайла.Заголовок = "Выберите файлы";
	Если ДиалогОткрытияФайла.Выбрать() Тогда
		ПутьКФайлу = ДиалогОткрытияФайла.ПолноеИмяФайла;
		// Получение двоичные данные файла
		ДвоичныеДанные = Новый ДвоичныеДанные(ПутьКФайлу);
		// Передача двоичных данные на сервер
		ПрикрепитьФайлСервер(ДвоичныеДанные);
	Иначе
		Текст = "ru = ""Файл(ы) не выбран!""; en = ""File(s) not selected!""";
		Предупреждение(НСтр(Текст));
	КонецЕсли;      	
КонецПроцедуры            
&НаСервере
Процедура ПрикрепитьФайлСервер(ДвоичныеДанные) // Обработчик на сервере записи файла в ИБ 
	// Трансформируем объект формы в справочник-объект
	ОбъектТекущий = РеквизитФормыВЗначение("Объект");   	
	// Присваиваем новое значение реквизиту "Данные"
	ОбъектТекущий.Данные = Новый ХранилищеЗначения(ДвоичныеДанные); 	
	// Сохраняем изменения
	ОбъектТекущий.Записать(); 		
КонецПроцедуры

 

Если описать алгоритм в общих чертах, то сначала на клиенте выбирается файл с диска. Полученные двоичные данные файла отправляются на сервер, где записываются в информационную базу, а именно в реквизит "Данные" текущего элемента справочника. 

 

В принципе все работает. При открытии элемента мы можем считывать эти данные по необходимости. Если, например, в реквизите сохранено изображение, то мы можетм получить его и вывести в поле формы. Такое решение имеет место быть, но в большинстве задач использовать реквизит с типом значения "ХранилищеЗначения" в справочниках и документах не оптимально. И вот почему...

Влияние на производительность

Проведем несколько тестов на производительность. В тестах будут использоваться два элемента справочника "Товары" с прикрепленным файлом и без. Размер прикрепленного файла составляет 5 мегабайт.

 

Все тесты проводятся с помощью обработки "ПолучениеЭлемента" в тестовой конфигурации. Скачать данную конфигурацию Вы можете по ссылке в конце статьи.

 

Замерим время открытие элементов справочника "Товары". Для открытия элемента используется метод глобального контекста "ОткрытьЗначение()", в качестве параметра которому передается ссылка на элемент. Выполним замер времени открытия с помощью стандартного интруемента замера производительности. Результаты представлены на следующем скриншоте:

Изображение

Как мы видим, время открытия элемента с прикрепленным файлом больше в 10 раз! Сделаем другой тест. Выполним метод "ПолучитьОбъект()" для ссылки на элемент справочника товары. Результат теста Вы можете видеть на следующем скриншоте.

Изображение

Разница весьма существенная. Получение элемента без прикрепленного файла отрабатывает быстре в 194 раза! 

 

Происходит это потому, что метод "ПолучитьОбъект()" получает все данные из реквизитов элемента справочника по ссылке. Соответственно, метод получает значения не только реквизитов "Код" и "Наименование", но и значение реквизита "Данные". Если в нем хранятся двоичные данные размером 5 мегабайт (как в нашем примере), то при получении объекта эти данные помещаются в оперативную память (как и остальные реквизиты) и затем передаются на клиентскую сторону. Именно получение данных из этого реквизита увеличивает время получения объекта элемента. Если же используется тонкий канал связи, то время открытия увеличится еще более значительно из-за передачи большого объема информации по сети.

 

Примечание: при выполнении метода "ОткрытьЗначение()" также сначала получается объект элемента справочника, а затем трансформируется в объект формы и передается на клиент (для управляемых форм). То есть, при открытии элемента по ссылке получение объекта также выполняется.

 

Проведем последний тест на время открытия и записи элемента справочника с прикрепленным файлом и без него. Результат представлен на следующем скриншоте.

 

Изображение

Закономерный результат. Время получения и, затем, записи для элемента справочника с прикрепленным файлом оказалось в ~19 раз больше. Как было сказано выше, при получении объекта получаются значения всех его реквизитов, в том числе и реквизита "Данные" в котором сохранены 5 мегабайт информации. При записи элемента этот объем данных вновь записывается в информационную базу. Следовательно, хранение данных в реквизите справочника (или документа) с типом "ХранилищеЗначения" отрицательно влияет на производительность как при получении объекта, так и при помещении его в информационную базу.

 

Какой же способ решения задачи по хранению данных для объектов информационной базы наиболее правильный?

Правильное решение

Если мы посмотрим на реализацию данного механизма в типовых конфигурациях, то увидим, что для объектов дополнительная информация хранится в отдельной таблице регистра сведений. Вот так, например, выглядит механизм присоединенных файлов в типовой конфигурациии "Управление торговлей" версии 11.

Изображение

Справочник "Номенклатура" является владельцем для справочника "НоменклатураПрисоединенныеФайлы". Тот в свою очередь связан с регистрам сведений "ПрисоединенныеФайлы", измерение которого "ПрисоединенныйФайл" ссылается на его элемент. Таким образом, данные, прикрепляемые к объектам информационной базы, фактически хранится в таблице регистра сведений, на работу которого объекм хранимых данных в ресурсе практически не влияет. Промежуточный справочник "НоменклатураПрисоединенныеФайлы" необходим для хранения дополнительной информации для присоединенного файла, а тажке для поддержки обращения к присоединенному файлу по ссылке.

 

Все выше сказанное еще раз подтверждает огромное влияние на производительность правильно разработанной структуры метаданных конфигурации.

 

Тестовая конфигурация с примером из статьи: LINK.

 
0
Читайте также
Восстановление потерянных реквизитов документов v 7.7
В ранее записанных и проведённых документах пропали некоторые реквизиты. В отчётах полный бардак. Как я решил эту проблему.
Про общие реквизиты
Общие реквизиты-особенности
Разработки
Поиск повторяющихся элементов справочников. ДЛЯ ЛЮБОЙ КОНФИГУРАЦИИ 7.7
Обработка для поиска дубляжей элементов справочников для 1С7.7(любой)
Доступ к реквизитам справочника в 1с7.7 для каждого пользователя
Разработка разграничивает доступ к реквизитам справочника в 1С 7.7
Загрузка справочников и документов из excel в 1С 8
"Обработка для загрузки документов и справочников из Excel"
Еще от автора
≡ к списку статей