gifts2017

Сравнение производительности различных техник проведения документов в 1С:Предприятие 8.1, с выборкой из табличной части и регист

Опубликовал Provlax (Provlax) в раздел Программирование - Практика программирования

Целью данной статьи является сравнение трех различных способов проведения документов по регистру накопления, в программно продукте 1С:Предприятие 8.1 с выборкой из табличной части документа и регистра накопления:
• Проведение с использованием соединения виртуальной таблицей регистра накопления с временной таблицей. В условиях виртуальной таблицы регистра накопления используется вложенный запрос к временной таблице; (далее по тексту – «Техника проведения с временными таблицами»);
• Проведение с использованием соединения виртуальной таблицей регистра накопления с вложенным запросом. В условиях виртуальной таблицы регистра накопления используется вложенный запрос к табличной части документа (далее по тексту – «Техника проведения с вложенными запросами»);
• Проведение с использованием соединения виртуальной таблицей регистра накопления с вложенным запросом. В условиях виртуальной таблицы регистра накопления используется список значений, полученный выгрузкой из табличной части документа (далее по тексту – «Техника проведения со списком значений»).
Блог автора: http://provlax.livejournal.com/
Дата написания: Октябрь 2007

(с) Статья может свободно копироваться, цитироваться и размещаться, при условии некоммерческого использования и сохранения ссылки на сайт автора.

Целью данной статьи является сравнение трех различных способов проведения документов по регистру накопления, в программно продукте 1С:Предприятие 8.1 с выборкой из табличной части документа и регистра накопления (тексты модулей проведения всех тестируемых техник приведены в приложении к статье):

• Проведение с использованием соединения виртуальной таблицей регистра накопления с временной таблицей. В условиях виртуальной таблицы регистра накопления используется вложенный запрос к временной таблице; (далее по тексту – «Техника проведения с временными таблицами»);

• Проведение с использованием соединения виртуальной таблицей регистра накопления с вложенным запросом. В условиях виртуальной таблицы регистра накопления используется вложенный запрос к табличной части документа (далее по тексту – «Техника проведения с вложенными запросами»);

• Проведение с использованием соединения виртуальной таблицей регистра накопления с вложенным запросом. В условиях виртуальной таблицы регистра накопления используется список значений, полученный выгрузкой из табличной части документа (далее по тексту – «Техника проведения со списком значений»);

Используемое, при тестировании, оборудование и программное обеспечение:
• 1С: Предприятие 8.1 (8.1.8.76)
• HP Proliant ML350 (2 процессора Intel(R) Xeon(R) CPU 5130@2Ghz, ОЗУ 2 Gb, ОС: Windows 2003 Server x64 ed)

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

• Справочник «Номенклатура»
• Документ «Приходная»
• Документ «Расходная»
• Обработка «Создание справочников» (используется для генерации любого количества справочников)
• Обработка «Создание документов» (используется для генерации любого количества документов)

Эту конфигурацию вы можете скачать здесь http://www.1cnastole.info/downloads.php?page_id=3.

Методика тестирования.

Используемая методика замера времени проведения различных техник очень проста. Генерировалось некоторое количество справочников «Номенклатура», создавался один большой документ «Приходная» по всем номенклатурам, генерировалось некоторое количество документов «Расходная».
Все замеры производительности выполнялись на последнем сгенерированном документе «Расходная», в котором и реализованы все 3 техники проведения документа.

Замер №1

Исходные данные:
Количество сгенерированных элементов в справочнике номенклатура: 10
Количество сгенерированных документов: 1
Количество строк табличной части документа: 10
Среднее количество строк табличной части введенных документов: 10

Результаты замера №1:


Все прошло, как и ожидалось.
1 Место: «Техника проведения с вложенными запросами»
2 Место: «Техника проведения со списком значений»
3 Место: «Техника проведения с временными таблицами»

Замер №2

Исходные данные:
Количество элементов в справочнике номенклатура: 10
Количество документов: 10
Количество строк табличной части документа: 10
Среднее количество строк табличной части введенных документов: 10

Результаты замера №2:


Практически та же самая картина, что и в первом замере.
1 Место: «Техника проведения с вложенными запросами»
2 Место: «Техника проведения со списком значений»
3 Место: «Техника проведения с временными таблицами»

Замер №3

Количество элементов в справочнике номенклатура: 100
Количество документов: 100
Количество строк табличной части документа: 100

Результаты замера №3:


Произошла смена 2 и 3 места.
1 Место: «Техника проведения с вложенными запросами»
2 Место: «Техника проведения с временными таблицами»
3 Место: «Техника проведения со списком значений»

Замер №4


Количество элементов в справочнике номенклатура: 100
Количество документов: 1000
Количество строк табличной части документа: 100
Среднее количество строк табличной части введенных документов: 100

Результаты замера №4:


Пока ничего не изменилось.
1 Место: «Техника проведения с вложенными запросами»
2 Место: «Техника проведения с временными таблицами»
3 Место: «Техника проведения со списком значений»

Замер №5

Количество элементов в справочнике номенклатура: 10 000
Количество документов: 100 000
Количество строк табличной части документа: 1000
Среднее количество строк табличной части введенных документов: 1000

Результаты замера №5:
О, как!!! :) При генерации документов 1С-ка запнулась на номере 79898, размер базы составил 5 Гб. Однако стоит заметить, что элементы справочника «Номенклатуры» после генерации документов, создались нормально, и количество элементов в 10 000 было достигнуто безо всяких ошибок.


Ну да ладно немного изменим исходные данные:

Количество элементов в справочнике номенклатура: 10 000
Количество документов: 79 898
Количество строк табличной части документа: 1000
Среднее количество строк табличной части введенных документов: 1000


Произошла смена лидера.
1 Место: «Техника проведения с временными таблицами»
2 Место: «Техника проведения с вложенными запросами»
3 Место: «Техника проведения со списком значений»

Замер № 6

Количество элементов в справочнике номенклатура: 10 000
Количество документов: 79 898
Количество строк табличной части документа: 10 000
Среднее количество строк табличной части введенных документов: 1000

Результаты замера №6:
О, как!!! :) При проведении документа с количеством строк в табличной части 10 000 снова вылезла ошибочка. По логике вещей, попробую удалить 10 ранее введенных документов, в которых количество строк 1000, и…


Сработало!

Снова корректируем исходные данные.

Количество элементов в справочнике номенклатура: 10 000
Количество документов: 79 888
Количество строк табличной части документа: 10 000
Среднее количество строк табличной части введенных документов: 1000


Все остались на своих местах.
1 Место по производительности: «Техника проведения с временными таблицами»
2 Место по производительности: «Техника проведения с вложенными запросами»
3 Место по производительности: «Техника проведения со списком значений»

На сем замеры закончились, перейдем к выводам.

Вывод.

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

Приложение 1. Процедура «Техника проведения с временными таблицами»

//Проведение по регистрам с использованием временной таблицы
Процедура Проведение1()
	//Создание временной таблицы с полями Номенклатура, Количество, Сумма из табличной
	//части документа со сверткой дублей строк
	МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
	Запрос1 = Новый Запрос;
	Запрос1.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;
	Запрос1.Текст= "ВЫБРАТЬ
 | РасходнаяТовары.Номенклатура,
 | СУММА(РасходнаяТовары.Количество) КАК Количество,
 | СУММА(РасходнаяТовары.Сумма) КАК Сумма
 |ПОМЕСТИТЬ ВременнаяТаблица
 |ИЗ
 | Документ.Расходная.Товары КАК РасходнаяТовары
 |ГДЕ
 | РасходнаяТовары.Ссылка = &Ссылка
 |
 |СГРУППИРОВАТЬ ПО
 | РасходнаяТовары.Номенклатура"
	;
	Запрос1.УстановитьПараметр("Ссылка",Ссылка);
	Запрос1.Выполнить();
	//Соединение временной таблицы с регистром накопления
	Запрос2 = Новый Запрос;
	Запрос2.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;
	Запрос2.Текст= "ВЫБРАТЬ
 | ВременнаяТаблица.Номенклатура,
 | ВременнаяТаблица.Количество,
 | ВременнаяТаблица.Сумма,
 | ОстаткиНоменклатурыОстатки.КоличествоОстаток,
 | ОстаткиНоменклатурыОстатки.СебестоимостьОстаток
 |ИЗ
 | ВременнаяТаблица КАК ВременнаяТаблица
 | ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиНоменклатуры.Остатки(,Номенклатура В (ВЫБРАТЬ РАЗЛИЧНЫЕ
 | Номенклатура
 | ИЗ ВременнаяТаблица)) КАК ОстаткиНоменклатурыОстатки
 | ПО ВременнаяТаблица.Номенклатура = ОстаткиНоменклатурыОстатки.Номенклатура
 |
 |ДЛЯ ИЗМЕНЕНИЯ
 | РегистрНакопления.ОстаткиНоменклатуры.Остатки"
	;
	Выборка = Запрос2.Выполнить().Выбрать();
	МенеджерВременныхТаблиц.Закрыть();
	
	//проведение по регистрам накопления
	Пока Выборка.Следующий() Цикл
		Движение = Движения.ОстаткиНоменклатуры.Добавить();
		Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
		Движение.Период = Дата;
		Движение.Номенклатура = Выборка.Номенклатура;
		Движение.Количество = Выборка.Количество/3;
		Движение.Себестоимость = ?(Выборка.КоличествоОстаток=Null,0,Выборка.СебестоимостьОстаток/Выборка.КоличествоОстаток/3);
		
		Движение = Движения.Продажи.Добавить();
		Движение.Период = Дата;
		Движение.Номенклатура = Выборка.Номенклатура;
		Движение.Сумма = Выборка.Сумма/3;
		Движение.Себестоимость = ?(Выборка.КоличествоОстаток=Null,0,Выборка.СебестоимостьОстаток/Выборка.КоличествоОстаток/3);
	КонецЦикла;
	
	Движения.ОстаткиНоменклатуры.Записать();
	Движения.Продажи.Записать();
	
КонецПроцедуры



Приложение 2. Процедура «Техника проведения с вложенными запросами»

//Проведение по регистрам с использованием вложенных запросов для соединения и условия виртуальной таблицы регистра
Процедура Проведение2()
	//Соединение регистра накопления с вложенным запросом,
	//в условии виртуальной таблицы также используется вложенный запрос
	//получающий свернутый список номенклатуры из документа
	Запрос4 = Новый Запрос;
	Запрос4.Текст="ВЫБРАТЬ
 | ВложенныйЗапрос.Номенклатура,
 | ВложенныйЗапрос.Количество,
 | ВложенныйЗапрос.Сумма,
 | ОстаткиНоменклатурыОстатки.КоличествоОстаток,
 | ОстаткиНоменклатурыОстатки.СебестоимостьОстаток
 |ИЗ
 | (ВЫБРАТЬ
 | РасходнаяТовары.Номенклатура КАК Номенклатура,
 | СУММА(РасходнаяТовары.Количество) КАК Количество,
 | СУММА(РасходнаяТовары.Сумма) КАК Сумма
 | ИЗ
 | Документ.Расходная.Товары КАК РасходнаяТовары
 | ГДЕ
 | РасходнаяТовары.Ссылка = &Ссылка
 | 
 | СГРУППИРОВАТЬ ПО
 | РасходнаяТовары.Номенклатура) КАК ВложенныйЗапрос
 | ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиНоменклатуры.Остатки(
 | ,
 | Номенклатура В
 | (ВЫБРАТЬ РАЗЛИЧНЫЕ
 | РасходнаяТовары.Номенклатура
 | ИЗ
 | Документ.Расходная.Товары КАК РасходнаяТовары
 | ГДЕ
 | РасходнаяТовары.Ссылка = &Ссылка)) КАК ОстаткиНоменклатурыОстатки
 | ПО ВложенныйЗапрос.Номенклатура = ОстаткиНоменклатурыОстатки.Номенклатура
 |
 |ДЛЯ ИЗМЕНЕНИЯ
 | РегистрНакопления.ОстаткиНоменклатуры.Остатки"
	;
	Запрос4.УстановитьПараметр("Ссылка", Ссылка);
	Выборка = Запрос4.Выполнить().Выбрать();
	
	//проведение по регистрам накопления
	Пока Выборка.Следующий() Цикл
		Движение = Движения.ОстаткиНоменклатуры.Добавить();
		Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
		Движение.Период = Дата;
		Движение.Номенклатура = Выборка.Номенклатура;
		Движение.Количество = Выборка.Количество/3;
		Движение.Себестоимость = ?(Выборка.КоличествоОстаток=0,0,Выборка.СебестоимостьОстаток/Выборка.КоличествоОстаток/3);
		
		Движение = Движения.Продажи.Добавить();
		Движение.Период = Дата;
		Движение.Номенклатура = Выборка.Номенклатура;
		Движение.Сумма = Выборка.Сумма/3;
		Движение.Себестоимость = ?(Выборка.КоличествоОстаток=0,0,Выборка.СебестоимостьОстаток/Выборка.КоличествоОстаток/3);
	КонецЦикла;
	
	Движения.ОстаткиНоменклатуры.Записать();
	Движения.Продажи.Записать();

КонецПроцедуры



Приложение 3. Процедура «Техника проведения со списком значений»

//Проведение по регистрам с использованием вложенного запроса для соединения, в условия виртуальной используется 
//свернутый список номенклатуры из таблицы документа
Процедура Проведение3()
	
	//Формирование свернутого списка номенклатуры из таблицы документа
	ТЗ = Товары.Выгрузить();
	ТЗ.Свернуть("Номенклатура","Количество,Сумма");
	Масс = ТЗ.ВыгрузитьКолонку("Номенклатура");
    СписокНоменклатуры2 = Новый СписокЗначений;
    СписокНоменклатуры2.ЗагрузитьЗначения( Масс);
    //Соединение регистра накопления с вложенным запросом, 
	//в условии виртуальной таблицы также используется СписокНоменклатуры
	Запрос5 = Новый Запрос;
	Запрос5.Текст="ВЫБРАТЬ
 | ВложенныйЗапрос.Номенклатура,
 | ВложенныйЗапрос.Количество,
 | ВложенныйЗапрос.Сумма,
 | ОстаткиНоменклатурыОстатки.КоличествоОстаток,
 | ОстаткиНоменклатурыОстатки.СебестоимостьОстаток
 |ИЗ
 | (ВЫБРАТЬ
 | РасходнаяТовары.Номенклатура КАК Номенклатура,
 | СУММА(РасходнаяТовары.Количество) КАК Количество,
 | СУММА(РасходнаяТовары.Сумма) КАК Сумма
 | ИЗ
 | Документ.Расходная.Товары КАК РасходнаяТовары
 | ГДЕ
 | РасходнаяТовары.Ссылка = &Ссылка
 | 
 | СГРУППИРОВАТЬ ПО
 | РасходнаяТовары.Номенклатура) КАК ВложенныйЗапрос
 | ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиНоменклатуры.Остатки(, Номенклатура В (&СписокНоменклатуры)) КАК ОстаткиНоменклатурыОстатки
 | ПО ВложенныйЗапрос.Номенклатура = ОстаткиНоменклатурыОстатки.Номенклатура
 |
 |ДЛЯ ИЗМЕНЕНИЯ
 | РегистрНакопления.ОстаткиНоменклатуры.Остатки"
	;
	Запрос5.УстановитьПараметр("СписокНоменклатуры", СписокНоменклатуры2);
	Запрос5.УстановитьПараметр("Ссылка",Ссылка);
	Выборка = Запрос5.Выполнить().Выбрать();	
	
	//проведение по регистрам накопления
	Пока Выборка.Следующий() Цикл
		Движение = Движения.ОстаткиНоменклатуры.Добавить();
		Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
		Движение.Период = Дата;
		Движение.Номенклатура = Выборка.Номенклатура;
		Движение.Количество = Выборка.Количество/3;
		Движение.Себестоимость = ?(Выборка.КоличествоОстаток=0,0,Выборка.СебестоимостьОстаток/Выборка.КоличествоОстаток/3);
		
		Движение = Движения.Продажи.Добавить();
		Движение.Период = Дата;
		Движение.Номенклатура = Выборка.Номенклатура;
		Движение.Сумма = Выборка.Сумма/3;
		Движение.Себестоимость = ?(Выборка.КоличествоОстаток=0,0,Выборка.СебестоимостьОстаток/Выборка.КоличествоОстаток/3);
	КонецЦикла;
	
	Движения.ОстаткиНоменклатуры.Записать();
	Движения.Продажи.Записать();
	
КонецПроцедуры
 

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Олег Ромазанов (programmer-1c2007) 26.11.07 11:00
Зачем вот это:

Движения.ОстаткиНоменклатуры.Записать();
Движения.Продажи.Записать();

???
2. Provlax (Provlax) 26.11.07 12:36
В процедуре проведения, эти процедуры 1,2,3 идут одна за другой. Движения.ОстаткиНоменклатуры.Записать(), Движения.Продажи.Записать()
необходимы для более точной фиксации времени проведения каждой процедуры в тесте. Если движения не записывать в каждой процедуре, то время, необходимое на запись движений не будет учтено при замере производительности.
3. Олег Ромазанов (programmer-1c2007) 26.11.07 13:01
а кэш?
точнее было бы проводить отдельно проведение по каждой из схем.
просто 3 раза все документы - по 1, 2, и 3 схеме
4. Provlax (Provlax) 26.11.07 13:15
Первые замеры делались начиная со второго проведения одного документа, в этом случае кэш не влият (проверено экспериментально).
5. Роман Зиновьев (Широкий) 03.12.07 13:35
Проведение №1:
Вы не пробовали передать в запрос саму таблицу документа (которую помещаете во временную таблицу). Зачем нужно запросом получать эту же самую таблицу через ссылку?

Проведение №3:
Код
 
ТЗ = Товары.Выгрузить();
ТЗ.Свернуть("Номенклатура","Количество,Сумма");
Масс = ТЗ.ВыгрузитьКолонку("Номенклатура");
СписокНоменклатуры2 = Новый СписокЗначений;
СписокНоменклатуры2.ЗагрузитьЗначения( Масс);
Показать полностью


Можно заменить на
Код
 
Запрос5.УстановитьПараметр("СписокНоменклатуры", Товары.ВыгрузитьКолонку("Номенклатура"));
Показать полностью


Засекать нужно было бы просто время получения данных запросов...
И было бы очень неплохо получить результаты в клиент-серверном варианте.

З.Ы. По отношению ко всем запросам - попробуйте переделать логику запросов с левого соединения на объединение - и замертить время

6. Gamm (Gamm) 04.12.07 15:54
Мне кажется некорректный способ тестирования. Запись регистров самая длительная операция поэтому и результаты не столь показательны. Надо бы провести тестирование скорости выполнения только запросов.
7. Buran_ (Yasen) 03.01.08 20:15
Подход к тестированию основательный. Но: временные таблицы хорошо работают на серверных базах. Да и вряд ли кто-то вздумает использовать базу 5Гб в файловом режиме.
Так что тестировать стоило бы в серверном варианте и желательно сравнивая с DB2
boggonzikov; support; +2 Ответить
8. Станислав Турчинский (Istur) 25.05.10 16:49
(0) Вместо рисунков везде пустые прямоугольники((
9. Z-z-z (ZLENKO) 07.07.10 12:33
На MS SQL 2005 оптимизатор запросов сильно "лажает" если статистика хоть немного устарела в варианте с "вложенными запросами" и реальная картина получается совсем другой. Я этот вариант никогда не использую. В остальном согласен - на маленьких документах быстрее работает список значений, на больших - временная таблица.
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа