Имя: Пароль:
1C
1С v8
Ускорить запись в независимый РС большого кол-ва данных
0 ИС-2
 
naïve
11.06.14
13:54
3 измерения, при записи делается отбор по одному из них.
В набор записей загружается таблица с > 500 000 записей. Скорость с которой записываются данные меня не устраивает.
За счет чего можно повысить скорость записи?

    НабЗапМобТоргВыгрузкаЦенНоменклатуры = РегистрыСведений.дик_МобТоргВыгрузкаЦенНоменклатуры.СоздатьНаборЗаписей();
    НабЗапМобТоргВыгрузкаЦенНоменклатуры.Отбор.Менеджер.Установить(Отдел);
    НабЗапМобТоргВыгрузкаЦенНоменклатуры.Прочитать();
    НабЗапМобТоргВыгрузкаЦенНоменклатуры.Загрузить(ЦеныСИдентификаторами);
    НабЗапМобТоргВыгрузкаЦенНоменклатуры.Записать();
1 H A D G E H O G s
 
11.06.14
13:57
УБрать
НабЗапМобТоргВыгрузкаЦенНоменклатуры.Прочитать();
2 МихаилМ
 
11.06.14
13:57
подобрать размер транзакции,
в несколько фоновых заданий если клиент-сервер
3 Aloex
 
11.06.14
14:02
(2) >>подобрать размер транзакции,
Что имеется в виду: SQL или количество записей?
4 ИС-2
 
naïve
11.06.14
14:05
(1) тогда же весь регистр затрется? Или ошибаюсь?
(2) это как? Записывать в транзакции через менеджер записи?
5 RomaH
 
naïve
11.06.14
14:08
(4) ошибаешься, ...но это не поможет - тормоза же не на чтении, а на записи?
6 Enders
 
11.06.14
14:09
(4) если установили отбор, то затрутся записи только по установленному отбору, которые вы и так трёте)
записывать в транзакции через набор записей, но допустим не сразу 500 000, а по 100 000 (вот это количество вам и надо найти опытным путем).
7 Enders
 
11.06.14
14:10
(5)На чтение тоже уходит время, пусть и не такое большое, но всё же ;)
8 RomaH
 
naïve
11.06.14
14:11
(6) а как писать набор из 2 записей которые идут в одномнаборе разными транзакциями?
ведь для этого надо разделить их по отборам.... или как?
9 Fragster
 
гуру
11.06.14
14:11
пиши по 5000 без очищения набора.
10 Enders
 
11.06.14
14:12
(8) Записать(Ложь), не?
11 RomaH
 
naïve
11.06.14
14:13
т.е. просто так взять и разделить 500 на 5 по 100 не очень-то и получится
нужно одно из измерений в отборе которое позволит разделить набор

а если это цены с измерениями:
Отдел и Номенклатура

по отделу 500 записей
а по номенклатуре - по одной

и как?
12 RomaH
 
naïve
11.06.14
14:13
(10) ага
13 Fragster
 
гуру
11.06.14
14:14
(11) не нужно
14 Enders
 
11.06.14
14:17
(11) просто так взять и разделить таблицу из 500 000, на 5 наборов по 100 000 очень-то и получится (цикл и запрос, как простейший вариант)
Просто сначала надо определиться какое кол-во записей в наборе оптимально, 100 000 это цифра с потолка)
15 Heckfy
 
11.06.14
14:18
(0) "Скорость с которой записываются данные меня не устраивает" - цифры в студию.
16 13_Mult
 
11.06.14
14:24
ИМХО Быстрее чем НаборЗаписей писать в базу только сиквелом напрямую
17 13_Mult
 
11.06.14
14:26
(16) Ещё ОбменДанными поставь, может побыстрее будет
18 andreymongol82
 
11.06.14
14:27
Вариант поиграться еще с индексируемыми полями. Часть убрать, часть добавить.
19 milan
 
11.06.14
14:34
Я через менеджер записи пишу, скорость порядка 50 записей в секунду. Имхо дергать набор записей каждый раз накладно выйдет.
20 Serginio1
 
11.06.14
14:47
Писать напрямую используя Merge
v8: _SimpleKey и его установка
21 kihor
 
11.06.14
16:13
(19) Насколько я знаю, менеджер записи внутри себя все равно использует набор записей - так что, я бы рекомендовал наоборот. Поправьте, если я не прав.
22 Maxus43
 
11.06.14
16:15
менеджер работает с одной записью, а набор со многими сразу
23 mkkd
 
11.06.14
16:17
(0)создать записи в нужном количестве на 1С а потом проапдейтить на SQL
24 kihor
 
11.06.14
18:14
(22) Я имел в виду, что менеджер это просто удобная "обертка" вокруг набора записей и не рекомендуется его использовать с точки зрения производительности.
25 ИС-2
 
naïve
16.06.14
09:34
(15) 500 000 - 20 минут и это в тестовой базе, где ни кого нет
26 МоеИмя
 
16.06.14
09:41
(25) База скульная или файло ? Какая скорость Вас устроила бы ?
27 ИС-2
 
naïve
16.06.14
10:05
(26) sql
1 секунда меня устроит :)
28 Serginio1
 
16.06.14
10:29
(27) Секунда не получится. У меня были прайсы по 4 миллиона, то через Merge апдейт был порядка 2 минут включая булк в темповую таблицу . А вот инсерт был уже порядка 2 минут. Правда общая таблица была около 60 миллионов записей.
29 Serginio1
 
16.06.14
10:29
Инсерт порядка 20 минут
30 ivanovnm
 
16.06.14
11:04
(5) А на чтение время не тратится?
31 ivanovnm
 
16.06.14
11:08
(21) Именно так пишут в книжках по 1С
(22) Менеджер работает с одной записью, но использует для работы НаборЗаписей
32 hhhh
 
16.06.14
11:34
(30) зачем читать, если всё удаляется?
33 degot
 
16.06.14
11:57
(0)bcp.exe
быстрее вряд ли что-то есть
34 ИС-2
 
naïve
17.06.14
10:24
(33) у кого-нибудь есть пример работы через bcp? кроме http://infostart.ru/public/238160/
35 ИС-2
 
naïve
17.06.14
11:29
ап.

Можно как-то ускорить за счет блокировок?
36 rsv
 
17.06.14
11:37
(35) Да никак . Копайте в сторону bcp. (34) Взлетело  ?
37 rsv
 
17.06.14
11:40
С точки зрения профайлера запись набора  выглядит  как порционная запись. т.е.  сервер приложений задумывается на N е время - потом идет запись . Потом опять думает - потом опять запись.
38 0xFFFFFF
 
17.06.14
11:54
(0) что это за извращенная запись с отбором и прочитать.
Без них никак не обойтись? В лоб писать просто и все. Ну можно замерить - в транзакции по 1000 штук - возможно быстрее будет.
39 РенеДекарт
 
17.06.14
12:05
(38) проблема не в чтении, а в записи.
1С очень долго пишет десятки тысяч записей.
40 Bober
 
17.06.14
12:10
(0)
- опиши структуру регистра (со всеми свойствами у каждого измерения, ресурса, реквизита).
- подключена-ли таблица к планам обмена?
- при отборе по менеджеру в регистре уже есть записи по нему?
41 РенеДекарт
 
17.06.14
12:13
(36)>>Копайте в сторону bcp.
с чего вы взяли, что "В набор записей загружается таблица с > 500 000 записей" - это у них единая таблица в SQL?
42 ИС-2
 
naïve
17.06.14
12:14
(36) еще не смотрел.
(37) т.е запись в транзакции фикция т.к Sql сам решает когда и что писать?
(38) код запси в транзакции правльно написал
43 ИС-2
 
naïve
17.06.14
12:14
#Если Клиент тогда
    Сообщить("Начало очистки цен: " + ТекущаяДата());
    #КонецЕсли
    НабЗапМобТоргВыгрузкаЦенНоменклатуры = РегистрыСведений.дик_МобТоргВыгрузкаЦенНоменклатуры.СоздатьНаборЗаписей();
    НабЗапМобТоргВыгрузкаЦенНоменклатуры.Отбор.Менеджер.Установить(Отдел);
    ////НабЗапМобТоргВыгрузкаЦенНоменклатуры.Прочитать();
    //НабЗапМобТоргВыгрузкаЦенНоменклатуры.Загрузить(ЦеныСИдентификаторами);
    НабЗапМобТоргВыгрузкаЦенНоменклатуры.Записать();    
    
    #Если Клиент тогда
    Сообщить("Конец очистки цен: " + ТекущаяДата());
    Сообщить("Начало записи цен (" + ЦеныСИдентификаторами.Количество() +"): " + ТекущаяДата());
    #КонецЕсли
    НачатьТранзакцию();
    сч = 0;
    Для Каждого Стр из ЦеныСИдентификаторами Цикл
        МенЗап = РегистрыСведений.дик_МобТоргВыгрузкаЦенНоменклатуры.СоздатьМенеджерЗаписи();
        ЗаполнитьЗначенияСвойств(МенЗап,Стр);
        
        Если сч = 10000 Тогда
            ЗафиксироватьТранзакцию();
            НачатьТранзакцию();
            сч = 0;
            
            #Если Клиент тогда
            Сообщить(" Пакет: " + ТекущаяДата());
            #КонецЕсли
        КонецЕсли;
        
        МенЗап.Записать();
        сч = сч + 1;
    КонецЦикла;
    ЗафиксироватьТранзакцию();
44 РенеДекарт
 
17.06.14
12:17
(42)>>т.е запись в транзакции фикция т.к Sql сам решает когда и что писать?
у SQL свой механизм-оптимизатор записи, который да, ищет оптимальный вариант и при записи тоже.
45 Bober
 
17.06.14
12:25
(0) какая версия платформы и какой режим совместимости используется?
46 ИС-2
 
naïve
17.06.14
12:33
(40) 3 измерения, 4 ресурса, 1 реквзит. Измерение Менеджер проиндексировано.
к планам обмена не подлючено
Перед записью данные уже имеются (т.е записывается на их место)
(45) 8.2.18,  без использования совместимости
47 Йохохо
 
17.06.14
12:35
(43) МенЗап.Записать(); выполняется в транзакции
48 Йохохо
 
17.06.14
12:38
(43) что за жуть "Если сч = 10000 Тогда "
49 ИС-2
 
naïve
17.06.14
12:39
(47) перенести, что в условие         Если сч = 10000 Тогда

Но тогда будет записываться только 10000-я запись...
50 ИС-2
 
naïve
17.06.14
12:40
(48) размер транзакции
51 Бешеная Нога
 
17.06.14
12:40
сгруппируй свою таблицу по 3м полям измерений - сколько строк получится?
52 rsv
 
17.06.14
12:52
(41) Регистр в (0)  - одна таблица в скуле  . Предлагаю автору  как эталон  по времени "засунуть " данные в регистр напрямки . А потом сравнить время с  прикладным Записать().
53 rsv
 
17.06.14
12:53
Хотя на этот вопрос ответ в  (20) . Там и время уже приведено
54 Йохохо
 
17.06.14
12:58
(49) Если НЕ (СЧ % 10000) Тогда
и транзакции все равно вложенные
55 МихаилМ
 
17.06.14
13:02
(54)
1c8 не поддерживает вложенные транзакции
56 kosts
 
17.06.14
13:14

Для каждого СтрокаТаблицы Из ОтражениеВУчетеНабор1 Цикл

    // Запись в регистр сведений
    СтрокаНабора = Набор.Добавить();
    ЗаполнитьЗначенияСвойств(СтрокаНабора, СтрокаТаблицы);
    СтрокаНабора.НПП = НПП;
    СтрокаНабора.Документ = Ссылка;
    Если нпп % 25000 = 0 Тогда
        Набор.Записать(Ложь);
        Набор.Очистить();
    КонецЕсли;
    НПП = НПП + 1;

КонецЦикла;

Если Набор.Количество() > 0 Тогда
    Набор.Записать(Ложь);
КонецЕсли;
57 Йохохо
 
17.06.14
13:17
(55) зато поддерживает ошибки в них)
58 ИС-2
 
naïve
17.06.14
13:52
(51) все уже сгруппировано. А иначе как бы записалось...
(56) спс. Попробую, но это же вариант без транзакции.
(43) чудо-юдо записывалось почти 2 часа. Жуть. В топку
59 Мэс33
 
17.06.14
13:57
Меня тоже огорчает скорость записи в 1С.
1 документ - 1-2 секунды.
60 Bober
 
17.06.14
14:09
(46) клиент-сервер, х64, ms sql какой?
61 Bober
 
17.06.14
14:10
(46)  3 измерения - они все ссылочные? там составной тип?
62 Bober
 
17.06.14
14:11
Менеджер - первое измерение в списке?
63 ИС-2
 
naïve
18.06.14
09:42
(60) 64 разрядный, 2008, ссылочные, без составных типов.
(62) Да, менеджер первое измерение
64 Bober
 
18.06.14
11:53
(63)
- запись идет на сервере (тонкий клиент) или на клиенте (толстый клиент)?

(43) если менеджер первое измерение (63), то можно отключить индекс по нему, так как у независимого рс кластерный индекс идет по всем измерениям.
65 Bober
 
18.06.14
11:53
(63) еще момент, когда идет запись 500к записей, сколько там уже записей есть?
66 МихаилМ
 
18.06.14
12:14
еще можно ускорить запись в таблицы субд

уменьшив fill factor.

толко при расчете заполненности индекса нужно учесть прогноз увеличения таблицы, чтобы переполнение не наступило

либо периодически перестраивать кластерный индекс.
67 vi0
 
18.06.14
12:27
(0) почему не рассматриваешь совет в (2)
> в несколько фоновых заданий если клиент-сервер

?
68 ИС-2
 
naïve
18.06.14
12:33
(64) толстый
(65) примерно столько же с отбором по этому измерению
(67) Попробую, но после SQL. Можно программно создавать фоновые задания? Например у меня 10 отделов и на них надо 10 фоновых заданий.
69 Йохохо
 
18.06.14
12:38
вариант (56) то как?
70 Fragster
 
гуру
18.06.14
12:39
(68) вот тут есть http://infostart.ru/public/173394/
71 МихаилМ
 
18.06.14
12:40
(67)



без подбора размера транзакции бессмыслено
даже если разделить на не пересекающиеся потоки по КИ
72 Bober
 
18.06.14
13:45
(68) вариант с фоновыми не сделаешь, так как нужно будет все этот в логической транзакции поддерживать. Нужно тебе проведение этого документа вынести на сервер.
73 Bober
 
18.06.14
13:46
(58) еще вопрос, у тебя RLS используется на этой таблице?
74 ИС-2
 
naïve
18.06.14
13:48
(71) что такое потоки по КИ?
(72) у меня не проведение документа, а просто запись. Так, что транзакция одна.
Что такое логическая транзакция
(73) нет, РЛС тут нет
75 Bober
 
18.06.14
13:52
(74) если ты разнесешь все на несколько фоновых и какое из них крякнет, то тебе нужно откатить все назад в исходное состояние.
76 Бешеная Нога
 
18.06.14
13:52
кстати еще неплохая идея думаю:
1. разбиение таблицы с 500000 строк на подтаблицы с уникальными наборами по первому измерению (менеджер)
2. запуск фоновых заданий в количестве уникальных первых измерений (менеджер) и передачи в них своей таблицы. запись набора внутри фонового задания.

таким образом ты пакет в 500000 записей разобьешь на N пакетов и запишешь параллельно
77 vi0
 
18.06.14
14:01
посмотри если есть доступ
http://kb.1c.ru/articleView.jsp?id=72
78 Bober
 
18.06.14
14:06
(74) провел тест на своем стенде (клиент-сервер, x64, ms sql 2008).

в базе 4 справочника (номенклатура, виды цен, сотрудник, валюта)
регистр сведений:
измерения
    сотрудник
    вид цен
    номенклатура
ресурсы
   валюта
   цена
  реквизит
   дата записи

работа идет через тонкий клиент
запись 218792 записей
запись с замещением 16507 мс (16.5 сек)
запись с предварительной очисткой по сотруднику и запись без замещения: 22452 мс (22.5 сек)
79 Bober
 
18.06.14
14:07
(78) что подтверждает мою мысль, что запись 500к записей не может идти более 30 сек. А уж разговора про 20 минут вообще не идет.
80 Bober
 
18.06.14
14:22
вообще, когда смотришь как 1с записывает данные в регистр становится страшно:
INSERT INTO _InfoRg9111 (_Fld9112RRef,_Fld9113RRef,_Fld9114RRef,_Fld9115RRef,_Fld9116,_Fld9117,_SimpleKey) VALUES(P1,@P2,@P3,@P4,@P5,@P6,@P7)
и так с каждой строчкой

но, очищает записи по отбору хоть человечески.
DELETE FROM T1
FROM _InfoRg9111 T1
WHERE T1._Fld9112RRef = P1
81 ИС-2
 
naïve
18.06.14
14:27
(79) может влиять, что записываю из внешней обработке (т.е выполняется на клиенте) и работаю на локальной машине?
В рабочей базе код будет выполняться в серверном модуле

Админ озвучивал мысль, что скорость упирается в жесткий диск. Это может быть?
82 Bober
 
18.06.14
14:30
(81) может, Для этого нужно смотреть нагрузку на сервере и смотреть на работу SQL сервера. Но, эту работу уже должен проводить админ. Основная мысль, что запись 500к в течении 20 мин не в 1с, а в другом.
83 ИС-2
 
naïve
18.06.14
14:35
(82) интересно сколько пишется записей при закрытии месяца и с какой скоростью...
84 Bober
 
18.06.14
14:37
(81) сделал замер на толстом клиенте (обычное приложение)
19.1 сек
23.6 сек
85 vi0
 
18.06.14
14:39
(80) почему страшно?

> но, очищает записи по отбору хоть человечески.
кстати, такая штука провоцирует эскалацию, местами
в отличии от одиночных инсертов
86 Bober
 
18.06.14
14:45
(85) считаем, что блокировки управляемые.
87 vi0
 
18.06.14
14:47
(86) если не ошибаюсь, здесь управляемые блокировки не помогут
т.к. в sql все равно будет выполнена та же самая инструкция delete
88 Bober
 
18.06.14
14:50
(87) нужно почитать про этот момент на ИТС
89 ИС-2
 
naïve
18.06.14
15:02
(88) что можно почитать по поводу диагности проблемы (с чем идти к админу)
90 Bober
 
18.06.14
15:05
(89) админ должен смотреть нагрузку на дисковую подсистему в момент записи (если он подозревает ее). Так же нужно смотреть что происходит на сервере SQL, возможно там проблемы.
подбора статей
http://www.gilev.ru/article/
91 Bober
 
18.06.14
15:06
(89) можешь начать с того, что сделать пустую базу с 4 спр и РС и катать туда данные. Если при устаовке на тот же сервер 1с и тот же sql сервер проблем не будет, то нужно смотреть в сторону обслуживания sql сервера.
92 ИС-2
 
naïve
18.06.14
15:51
(90) спс.

Conn = Новый COMОбъект("ADODB.Connection");
    Conn.Connectionstring = СтрокаКоннекта;
    Conn.ConnectionTimeOut = 600;
    Conn.CursorLocation = 3; //dUseClient
    Conn.IsolationLevel = 4096; //adXactReadCommitted
    
    Попытка
        Conn.Open() ;
    Исключение
        Сообщить(ОписаниеОшибки());
        
        Возврат Ложь;
    КонецПопытки;
    
        Conn.BeginTrans();
        СтрокаЗапроса = "
        | DELETE FROM _InfoRg7295";
        
        Conn.Execute(СтрокаЗапроса,,128);//adExecuteNoRecords(123)

на Conn.Execute( вылетает с ошибкой

Произошла исключительная ситуация (Microsoft OLE DB Provider for SQL Server): Время ожидания запроса истекло

получается, что реально SQL медленно работает? Как повысить время ожидания?
93 DS
 
18.06.14
15:54
Conn.ConnectionTimeOut = 600;
?
94 ИС-2
 
naïve
18.06.14
15:58
(93) уже менял. Было 60
95 AMKahm
 
18.06.14
16:19
ConnectionTimeOut это для соединения с серваком.
"Indicates how long to wait while establishing a connection before terminating the attempt and generating an error."

Попробуй CommandTimeOut поставить.

BULK INSERT уже предлагали использовать?
96 Serginio1
 
18.06.14
16:44
(98) Да 20 28
97 Serginio1
 
18.06.14
16:46
98 Bober
 
18.06.14
20:26
(89) тебе и админу рекомендую
http://v8.1c.ru/metod/books/book.jsp?id=452
99 ИС-2
 
naïve
19.06.14
12:16
(95) спс. Помогло
100 Волшебник недоучка
 
19.06.14
12:27
100
101 Serginio1
 
19.06.14
14:10
(98) У меня стоит
Connection.CommandTimeOut=0;
    Connection.ConnectionTimeout = 0;
    Connection. CursorLocation= 3;
102 ИС-2
 
naïve
04.07.14
08:33
на сервере запись происходит гораздо быстрее
103 ИС-2
 
naïve
10.07.14
11:00
столкнулся с такой проблемой - конфликт блокировки. Но почему она возникла? Данные по этому измерению пишет только одно рег. задание. Чтение не выполнется. Может из-за объема данных (до 2,5 млн записей по этому измерения)

Надо в SQL 2008 изменить время ожидания для записи?

{ОбщийМодуль._Сервер.Модуль(2030)}: Ошибка при вызове метода контекста (Записать)
по причине:

по причине:
Конфликт блокировок при выполнении транзакции:
Microsoft SQL Native Client: Lock request time out period exceeded.
HRESULT=80040E31, SQLSrvr: SQLSTATE=HYT00, state=38, Severity=10, native=1222, line=1
104 ИС-2
 
naïve
23.07.14
08:16
для статистики надо анализировать сколько времени ушло на запись данных в регистр. Добавил реквизиты в регистр - Начало и КонецЗаписи.
Можно ли как-то быстро(!) после выполнения записи заполнить реквизит КонецЗаписи?
Мудить с журналом регистрации или другим регистром нет желания.
105 ДенисЧ
 
23.07.14
08:38
(104) Триггер на скуль повесь