Вход | Регистрация
 

Как-то можно ускорить запись в регистр сведений?

Как-то можно ускорить запись в регистр сведений?
Я
   Галахад
 
25.01.21 - 13:30
Код:

    ЗаписьXML = Новый ЗаписьXML;
    ЗаписьXML.УстановитьСтроку();
    Для каждого Стр Из ТаблицаЗаписей Цикл
        
        ЗаписьXML.ЗаписатьБезОбработки("INSERT INTO " + ТаблицаSQL);
        ЗаписьXML.ЗаписатьБезОбработки("([" + А + "], [" + В + "], [" + С + "], [" + Д + "], [" + Количество + "])");
        ЗаписьXML.ЗаписатьБезОбработки("VALUES ('"+Стр.А+"', '"+Стр.В+"', '"+Стр.С+"', '"+Стр.Д+"', '"+Стр.Количество+"')");
            
    КонецЦикла;
    ТекстТекущейИнструкции = ЗаписьXML.Закрыть();    
    
    
    Попытка
        
        Соединение.BeginTrans();
        Соединение.Execute(ТекстТекущейИнструкции,,128);
        Сообщить("Ок!");
        Соединение.CommitTrans();
        
    Исключение
        
        Сообщить(ОписаниеОшибки());
        Соединение.RollbackTrans();
        
    КонецПопытки;
   Галахад
 
1 - 25.01.21 - 13:30
Статистика:
Записей = 4 460, время = 427
   Галахад
 
2 - 25.01.21 - 13:33
Измерения А, В, С, Д - Строка
Ресурс - Число
Ведущее - Ложь
Основной отбор - Истина
   polosov
 
3 - 25.01.21 - 13:33
(0) Мы сами не местные. Это что за запись и в какой РС? Прямо в БД пытаешься писать?
Кто такое Соединение?
   ДенисЧ
 
4 - 25.01.21 - 13:33
булкой вставляй.
Или индексы убери все...
   Галахад
 
5 - 25.01.21 - 13:35
(3) Тип того.
Регистр в (2) описал.
Да.
Соединение  = Новый COMОбъект("ADODB.Connection");
   Галахад
 
6 - 25.01.21 - 13:35
(4) Пример есть?
Щас попробую.
   lEvGl
 
7 - 25.01.21 - 13:39
(6) булккопи в гугле примеры
   Галахад
 
8 - 25.01.21 - 13:40
(4) Отключил и "основной отбор"
Ведущее и Индексировать уже были отключены.
Результат:
Записей = 4 460, время= 488
   ДенисЧ
 
9 - 25.01.21 - 13:40
(6) В BOL точно есть
   lEvGl
 
10 - 25.01.21 - 13:41
+ на шарпе точно работает )
   Широкий
 
11 - 25.01.21 - 13:42
Пакетный инсерт?
   fisher
 
12 - 25.01.21 - 13:43
Измерения - длинные строки, что ли?
   Галахад
 
13 - 25.01.21 - 13:49
(9) (10) Окай.

(11) Угу. Посмотрю.

(12) Длинна - 5, 9, 9, 9
   polosov
 
14 - 25.01.21 - 13:51
   fisher
 
15 - 25.01.21 - 13:55
(13) Хм. Тогда странно. 10 записей в секунду как-то маловато. Да еще и в транзакции. А попробуй ради интереса транзакцию не через соединение делать, а через T-SQL.
ЗЫ. А зачем, если не секрет, ты текст запроса через ЗаписьXML готовишь?
   fisher
 
16 - 25.01.21 - 13:57
Хотя погоди. Для одной транзакции ты многовато данных пишешь. Попробуй для начала писать пачками по 100.
   Ёпрст
 
17 - 25.01.21 - 13:58
и транзакцию выкинь
   Галахад
 
18 - 25.01.21 - 14:01
(14) Спасибо.

(15) Хм. Там миллисекунды.
Ок. Но это уже не сегодня.
А как? Конкатенация - тормозная же операция.
   Fragster
 
19 - 25.01.21 - 14:02
вынеси         ЗаписьXML.ЗаписатьБезОбработки("INSERT INTO " + ТаблицаSQL);
        ЗаписьXML.ЗаписатьБезОбработки("([" + А + "], [" + В + "], [" + С + "], [" + Д + "], [" + Количество + "]) VALUES ");
 за цикл, скобки через запятую повтори
   Fragster
 
20 - 25.01.21 - 14:03
можно порциями по 1000 строк
   Fragster
 
21 - 25.01.21 - 14:04
вроде mssql стал такое поддерживать с 2008
   Timon1405
 
22 - 25.01.21 - 14:05
(18) СтрСоединить быстрее чем сложение строк через +
   fisher
 
23 - 25.01.21 - 14:05
(18) Да до меня только дошло, что у тебя там строка эпических размеров.
А, так у тебя больше 10000 в секунду залетает? А хочешь сколько? :)
Но в любом случае, если уменьшишь размер пакета на транзакцию, то некоторый прирост быть должен.
   Fragster
 
24 - 25.01.21 - 14:06
(22) записьXML самый быстрый по тестам
   Галахад
 
25 - 25.01.21 - 14:06
(16) (17)
Чот не особо изменилось...

Записей = 4 460, время= 437
   Галахад
 
26 - 25.01.21 - 14:07
Ладно, мне бежать пора. А вы пишите, не стесняйтесь. :-)
Завтра потестю.
   Широкий
 
27 - 25.01.21 - 14:07
(25) в 21 пакетный инсерт
   fisher
 
28 - 25.01.21 - 14:12
Ну, тогда в сторону "булок" был правильный пинок.
http://catalog.mista.ru/1c/articles/1009357/
   Конструктор1С
 
29 - 25.01.21 - 14:52
(4) булк это для больших объемов. А тут 4 тыщи
   lEvGl
 
30 - 25.01.21 - 14:57
(29) по коду из (0) текст запроса выглядит как
Insert A, B, C values 1, 2, 3
Insert A, B, C values 3, 2, 1
Insert A, B, C values 11, 22, 33

и так 4000 раз, я может и перфекционист, но когда столкнулся с таким вариантом вставки подумал что, что то не ладное, как минимум текст запроса потенциально может много весить, и это ерунда по сравнению с процессом интерпритации таких текстов двигателем sql
 
 
   Fragster
 
31 - 25.01.21 - 14:59
(30) см (19). да, и работает вставка оним запросом прям сильно быстрее
   sapphire
 
32 - 25.01.21 - 15:05
(0) Для очень большого объема записей вполне годно передать XML серверу и на стороне СУБД сделать вставку в таблицу из запроса к XML
   Конструктор1С
 
33 - 25.01.21 - 15:06
(31) ну да, надо объединить в один инсерт
   sapphire
 
34 - 25.01.21 - 15:08
+(32) если версия сервера поддерживает JSON, то в формате JSON
   sapphire
 
35 - 25.01.21 - 15:10
Хотя, 5К записей, действительно можно обычным текстом бабахнуть
   mistеr
 
36 - 25.01.21 - 15:43
(0) Главный вопрос — откуда данные приходят и в каком виде?
   Serg_1960
 
37 - 25.01.21 - 16:07
Я за вариант (19) и (20). Во-первых, не вижу смысла для каждого INSERT список полей повторять; во-вторых, можно и без списка полей обойтись, если автор указывает значения всех полей записи

INSERT INTO
таблица(список полей)
VALUES
(список значений 1),
(список значений 2),
...
(список значений 1000)
   fisher
 
38 - 25.01.21 - 16:08
(34) О. Прикольная мысль. Вроде с 2016 можно. Будем знать.
Через xml делал когда-то похожее. Шустро работало.
   fisher
 
39 - 25.01.21 - 16:09
Всяко лучше, чем через файлики.
   Галахад
 
40 - 26.01.21 - 07:26
Хм. Немного не тот результат я ожидал...

Пакетом. Время = 325
Построчно. Время = 243
   Галахад
 
41 - 26.01.21 - 07:27
Функция ДобавитьЗаписиСКЛПакетом(Соединение, ТаблицаSQL, Поля, МассивТаблиц)
    
    ВремяИтого = 0;
    
    Для каждого ТекТаблица Из МассивТаблиц Цикл
        
        КолСтрок = ТекТаблица.Количество();
        Сч = 0;
        
        ЗаписьXML = Новый ЗаписьXML;
        ЗаписьXML.УстановитьСтроку();
        ЗаписьXML.ЗаписатьБезОбработки("INSERT INTO " + ТаблицаSQL);
        ЗаписьXML.ЗаписатьБезОбработки("([" + Поля[0].Значение + "], [" + Поля[1].Значение + "], [" + Поля[2].Значение + "], [" + Поля[3].Значение + "], [" + Поля[4].Значение + "])");
        ЗаписьXML.ЗаписатьБезОбработки("VALUES");
        Для каждого Стр Из ТекТаблица Цикл
            
            Сч = Сч + 1;
            Если Сч = КолСтрок Тогда
                ЗаписьXML.ЗаписатьБезОбработки("('" + Стр[0] + "', '" + Стр[1] + "', '" + Стр[2] + "', '" + Стр[3] + "', '" + Стр[4] + "')");
            Иначе
                ЗаписьXML.ЗаписатьБезОбработки("('" + Стр[0] + "', '" + Стр[1] + "', '" + Стр[2] + "', '" + Стр[3] + "', '" + Стр[4] + "'),");
            КонецЕсли; 
            
        КонецЦикла; 
        ТекстТекущейИнструкции = ЗаписьXML.Закрыть();
        
        
        Начало = ТекущаяУниверсальнаяДатаВМиллисекундах();
        ВыполнитьИнструкциюСКЛ(Соединение, ТекстТекущейИнструкции);
        Окончание = ТекущаяУниверсальнаяДатаВМиллисекундах();
        ВремяИтого = ВремяИтого + (Окончание - Начало);
        

    КонецЦикла; 
    
    Сообщить("Пакетом. Время = " + ВремяИтого);
        
КонецФункции
   Галахад
 
42 - 26.01.21 - 07:27
Функция ДобавитьЗаписиСКЛ(Соединение, ТаблицаSQL, Поля, ТаблицаЗаписей)
    
    ЗаписьXML = Новый ЗаписьXML;
    ЗаписьXML.УстановитьСтроку();
    Для каждого Стр Из ТаблицаЗаписей Цикл
        
        ЗаписьXML.ЗаписатьБезОбработки("INSERT INTO " + ТаблицаSQL);
        ЗаписьXML.ЗаписатьБезОбработки("([" + Поля[0].Значение + "], [" + Поля[1].Значение + "], [" + Поля[2].Значение + "], [" + Поля[3].Значение + "], [" + Поля[4].Значение + "])");
        ЗаписьXML.ЗаписатьБезОбработки("VALUES ('" + Стр[0] + "', '" + Стр[1] + "', '" + Стр[2] + "', '" + Стр[3] + "', '" + Стр[4] + "')");
            
    КонецЦикла; 
    ТекстТекущейИнструкции = ЗаписьXML.Закрыть();    
    
    
    Начало = ТекущаяУниверсальнаяДатаВМиллисекундах();
    ВыполнитьИнструкциюСКЛ(Соединение, ТекстТекущейИнструкции);
    Окончание = ТекущаяУниверсальнаяДатаВМиллисекундах();
    ВремяВсего = Окончание - Начало;
    Сообщить("Построчно. Время = " + ВремяВсего);
        
КонецФункции
   Галахад
 
43 - 26.01.21 - 07:31
Процедура ВыполнитьИнструкциюСКЛ(Соединение, ТекстТекущейИнструкции)
    
    Попытка
        
        Соединение.Execute(ТекстТекущейИнструкции,,128);
        
    Исключение
        
        Сообщить(ОписаниеОшибки());
        
    КонецПопытки;    
    
        
КонецПроцедуры
   Fragster
 
44 - 26.01.21 - 10:34
а ты замерь какое место больше занимает, формирование инструкции пили выполнение запроса? может ты не там оптимизируешь вообще.
   Галахад
 
45 - 26.01.21 - 11:02
(44) Замеры установлены только на выполнение запросов. Формирование инструкций не учитывается.
   Ёпрст
 
46 - 26.01.21 - 11:06
(0) у тя строки что ле везде ? все 4 поля строковые ? Какой длины хоть ?
   Галахад
 
47 - 26.01.21 - 11:22
(46) Измерения - строки.
Длинна - 5, 9, 9, 9.
Пятое поле ресурс - число.
   Fragster
 
48 - 26.01.21 - 11:26
Сделай INSERT INTO ... WITH (TABLOCK)
и INSERT INTO ... WITH (NOLOCK)
   Fragster
 
49 - 26.01.21 - 11:27
хотя нолок здесь не применим, он на селект
   Fragster
 
50 - 26.01.21 - 11:28
вообще условия тестирования какие ? это отдельный физический сервер, я надеюсь? или ты (хотя бы) в цикле раз 10-50 повторяешь и мат ожидание нам сообщаешь?
   Галахад
 
51 - 26.01.21 - 12:10
(48) Плюс-минус пару процентов.

(50) Ну, такие себе условия. :-)
Нет, не отдельный.
Ну не 10-50, но раз по пять каждый.
   Галахад
 
52 - 26.01.21 - 14:34
Ну вот нашлась разгадка.

Оказывается построчно выполняется быстрее по простой причине - команда выполняется частично. :-)
   lEvGl
 
53 - 26.01.21 - 14:50
(52) а подробнее можно? не понял
инсерт знач, знач, знач
инсерт знач, знач, знач
инсерт знач, знач, знач

выполняется быстрее чем
инсерт знач, знач, знач
знач, знач, знач
знач, знач, знач
?
или в каждой итерации цикла запись?
   ДедМорроз
 
54 - 26.01.21 - 14:56
А кстати,если через Prepare и Execute делать построчно - насколько медленнее?
   ДедМорроз
 
55 - 26.01.21 - 14:59
Просто,каждый insert это трансляция текста запроса для исполнения,здесь - самая медленная операция.
   ДедМорроз
 
56 - 26.01.21 - 15:00
В adodb для prepare нужно установить текст запроса с параметрами и обновить информацию о параметрах.
   Вафель
 
57 - 26.01.21 - 15:01
а еще можно индексы на таблице приостановить а потом включить


Список тем форума
 
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.
Тема не обновлялась длительное время, и была помечена как архивная. Добавление сообщений невозможно.
Но вы можете создать новую ветку и вам обязательно ответят!
Каждый час на Волшебном форуме бывает более 2000 человек.