Имя: Пароль:
1C
1С v8
Быстрое создание группы документов
0 AlexeyAlexey Alexey
 
13.09.13
07:11
Поискал, пока ничего не нашел. Есть идея.
Есть документы одного типа. Каждый месяц создается много документов такого типа. Да так много, что занимает это целую ночь.
У меня стоит задача сделать эту операцию быстрее.
база на SQL.

Мысли: в 1С каждый документ создается отдельно. Каждый раз идет запись.
И даже если у тебя есть фактически данные в таблице значений, которую нужно положить в базу ввиде документа и его движений, то происходит это долго. При этом, если мы пишем а) 10 документов с одной строкой в ТЧ и б) 1 документ с 10 строками в табличной части и движениях, то вариант б произойдет гораздо быстрее. И дело скорее всего не только и не столько в процедурах ОбработкиПроведения и записи. Дело в самой операции внесения данных в БД.

И вот я думаю, было бы здорово затолкать все документы одной операцией. Как бы это можно было сделать?
1 grate
 
13.09.13
07:21
(0) Документы записываются в транзакции?
2 grate
 
13.09.13
07:31
(0) Документы записывать в одной транзакции, если на одну транзакцию не хватает памяти - то в нескольких (подобрать оптимальное количество документов в транзакции экспериментально).
Если при проведении документов выполняются запросы к БД - вынести обработку проведения в отдельную процедуру "массового проведения", чтобы получать данные одним или несколькими запросами и руками формировать наборы движений для каждого документа.
3 МихаилМ
 
13.09.13
07:32
Вы уже сделали замеры производительности ? тогда почему не написали об этом.


Вы уже поискали аналогичные темы на форуме? ссылки в студию.

работа программиста подразумевает наличие высшего образования
и как следствия хотя бы умения излагать "as is".
4 AlexeyAlexey Alexey
 
13.09.13
07:51
(1) (2) Попробую сделать документы в одной транзакции.
Я вообще думаю обойтись без обработок проведения, запросов к базе во время записи. Хочу сначала подготовить все данные для записи для всех документов и потом просто записывать.
(3) Замер производительности делал, но сейчас данных уже нет. Буду делать эксперимент по (1) и (2) - сделаю замер. На форуме такого не нашел.
5 МихаилМ
 
13.09.13
08:18
(4)
95% ,задающих вопромы здесь,  не умеют пользоваться поисковыми системами.
недостаток 1с - низкий порог вхождения в профессию.
как следствия море случайных ... людей.
6 МихаилМ
 
13.09.13
08:21
коли версия 1с клиент серверная ("база на SQL")

можете распараллелить запись фоновыми заданиями.
7 МихаилМ
 
13.09.13
08:23
(4)
"Попробую сделать документы в одной транзакции"

будет многократно медленнее - надежность враг производительности. закон количества - качества.
8 AlexeyAlexey Alexey
 
14.09.13
08:32
По поводу в одной транзакции я проверку делал так:

Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ ПЕРВЫЕ 300
|    РеализацияТоваровУслуг.Ссылка КАК Дока
|ИЗ
|    Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
|ГДЕ
|    РеализацияТоваровУслуг.Дата МЕЖДУ ДАТАВРЕМЯ(2013, 5, 31, 0, 0, 0) И ДАТАВРЕМЯ(2013, 8, 31, 23, 59, 59)
|    И РеализацияТоваровУслуг.Проведен";
    
Результат = Запрос.Выполнить();
    
Доки.Загрузить(Результат.Выгрузить());
    
//1 Проведение. Все документы в одной транзакции.
ДатаНачала = ТекущаяДата();
НачатьТранзакцию();
Для циклов = 0 по 19 Цикл
    ТекДока = Доки[циклов];
    ДокаБыл = ТекДока.Дока.ПолучитьОбъект();
    ДокаСозд = ДокаБыл.Скопировать();
    ДокаСозд.Дата = ДАТА(2013,09,30,01,01,01);
    ДокаСозд.Записать(РежимЗаписиДокумента.Проведение);
КонецЦикла;
ЗафиксироватьТранзакцию();
ДатаЗавершения = ТекущаяДата();
    
Сообщить("Проведение. Все документы в одной транзакции. Время работы: "+(ДатаЗавершения - ДатаНачала)+" секунд");
    
//2 Проведение. Без транзакций.
ДатаНачала = ТекущаяДата();
Для циклов = 0 по 19 Цикл
    ТекДока = Доки[циклов];
    ДокаБыл = ТекДока.Дока.ПолучитьОбъект();
    ДокаСозд = ДокаБыл.Скопировать();
    ДокаСозд.Дата = ДАТА(2013,09,30,01,01,01);
    ДокаСозд.Записать(РежимЗаписиДокумента.Проведение);
КонецЦикла;
ДатаЗавершения = ТекущаяДата();
    
Сообщить("Проведение. Без транзакций. Время работы: "+(ДатаЗавершения - ДатаНачала)+" секунд");

//3 Проведение. Каждый документ в своей транзакции.
ДатаНачала = ТекущаяДата();
Для циклов = 0 по 19 Цикл
    НачатьТранзакцию();
    ТекДока = Доки[циклов];
    ДокаБыл = ТекДока.Дока.ПолучитьОбъект();
    ДокаСозд = ДокаБыл.Скопировать();
    ДокаСозд.Дата = ДАТА(2013,09,30,01,01,01);
    ДокаСозд.Записать(РежимЗаписиДокумента.Проведение);
    ЗафиксироватьТранзакцию();
КонецЦикла;


Результат получился одинаковый. Так что поместить в одну транзакцию не помогло.
9 AlexeyAlexey Alexey
 
14.09.13
08:42
(6) Почитал немного про это, похоже мне это вполне подойдет. Постараюсь сделать запись несколькими фоновыми заданиями.
10 alexkr
 
14.09.13
10:25
(4) "Я вообще думаю обойтись без обработок проведения, запросов к базе во время записи. Хочу сначала подготовить все данные для записи для всех документов и потом просто записывать. "

Если это документ Событие или Электронное письмо, то вполне можно и так, а если это какой нить документ, у которого тьма движений и одни опираются на другие, что тогда?
К тому же периодически меняется структура регистров ( не часто но имеет место и такое), каждый раз править обработку или как тогда обходить обработки проведения?
Признаком хорошего тона в програмировании, всегда считалось умение максимально использовать типовой механизм с минимумом доработок.

Удачи в выборе решения!
11 Lama12
 
14.09.13
15:52
(8) Кто ж так делает транзакции для ускорения?
Делай весь цикл в одной транзакции.
Только смотри когда будет много объектов в транзакции, может наоборот снизится скорость.
Подбирай экспериментально.
12 AlexeyAlexey Alexey
 
15.09.13
08:09
(11) Там у меня для сравнения сразу 3 варианта. Первый вариант - весь цикл в одной транзакции. Но как показал эксперимент, время примерно одинаковое.
(10) Документ - Реализация товаров и услуг. Выставляется клиентам раз в месяц, их тьма тьмущая, от друг друга документы не зависят, так как это услуги. Но, спасибо за предупреждение.
(9) Провел эксперимент. Результат - в 2 раза быстрее.
Опирался на статью http://kb.mista.ru/article.php?id=696.
Каждое проведение делалось в своем фоновом задании. То есть в идеале, как мне кажется, должно было провестись со скоростью проведения одного документа. Видимо мешает для одного экземпляра проведения мешает блокировка таблиц длугим экземпляром (пока не знаю).
Как итог: 210 секунд циклических против 120 секунд фоновых на 300 документов для каждого варианта.
Причем время проведения прыгало, то в одну секунду проведет 10 документов, то промежуток между 2 проведениями составлял 7 секунд. С чем связано тоже пока не знаю.
13 AlexeyAlexey Alexey
 
15.09.13
08:12
Поскольку один вариант фоновый, то можно от одного лкиента запустить сразу два варианта, запустил, разница в итоге почти та же - 127 против 265 секунд.
14 hhhh
 
15.09.13
08:40
(13) вы ведь не проведение проверяете, а вот эту фигню

   ДокаБыл = ТекДока.Дока.ПолучитьОбъект();
    ДокаСозд = ДокаБыл.Скопировать();

в общем, фигней страдаете.  Хотя бы накопируйте изначально документов, хотя бы тысяч несколько, и потом проверяйте,  только проведение.
15 AlexeyAlexey Alexey
 
15.09.13
08:41
Еще попрбывал передавать в фоновую процедуру не по одной ссыле, а порциями по 50 штук. Время проведения 300 документов сократилось до 45 секунд.
16 AlexeyAlexey Alexey
 
15.09.13
09:23
Резюмирую, получилось ускориться благодаря проведению порциями в фоновых заданиях. Попробывал на 5000 документах. Результат - 2 минуты.
17 hhhh
 
15.09.13
09:53
(16) но зачем заниматься такой тупой работой? Ведь ясно, что вам надо делать один документ в день. В нем тысяча строчек ваших услуг. Не реализация, а как документ Отчет о розничных продажах.
18 AlexeyAlexey Alexey
 
20.09.13
08:34
(17) Нет, у нас клиенты - это организации, которым нужен весь комплект: акт, счет-факутра. Оплату они делают через банковский счет.
19 AlexeyAlexey Alexey
 
20.09.13
08:35
(17) А отчет о розничных продажах это для ККМ