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

Удаление из подчиненного периодического регистра сведений. Помогите оптимизировать код.

Удаление из подчиненного периодического регистра сведений. Помогите оптимизировать код.
Я
   Kongo2019
 
03.02.21 - 08:32
Доброго.
Удаление из подчиненного периодического регистра сведений. Помогите оптимизировать код.
Есть регистр сведений Хранилище акцизных марок.
Периодичность - По позиции регистратора.
Режим записи - Подчинение регистратору.
Измерение Марка, строка длина 160 символов, пишется туда типа такого
170300181766771018001JY3BOHGSSEHPTLU7N57B333G5QDVUZJPLXC3C57ID4X3K2SGV3BTPM5C7TISRHULGNEJ6XXDCIVKH6B6JIIPREFYDXJLMGAMYDT64AZK42ANKLL2MBSQSTSOJBHSDVOWA .
В ресурсах есть ОтметкаВыбытия – тип булево.
Остальные ресурсы в данном вопросе не важны.
У нас в основном в этом регистре одна марка может быть в двух записях.
Если производство, то это два регистратора отчет производства за смену типа ставит на баланс и ТТН где уставлен признак выбывшие.
Если мы купили и продали это два регистратора это Акт к ТТН и ТТН где уставлен признак выбывшие.
Нескорые марки могут туда - сюда кататься, будет несколько записей,  главная запись последняя, по ней надо смотреть ОтметкаВыбытия.
На текущий момент в регистре 38 миллионов записей.
Задача зачистить выбывшие марки, оставив данные только за последние полгода.
Пока сделал так. За 12 часов в среднем удаляется полмиллиона записей.
Помогите оптимизировать код. Пока только в голову приходит запустить на нескольких компах с разным диапазоном дат.

Процедура Кнопка1Нажатие(Элемент)
    //Удаление записей из регистра, подчиненного регистратору
    
    Сообщить("Начало запроса - " + ТекущаяДата());
    
    Запрос = Новый Запрос;
    
    Запрос.Текст = "ВЫБРАТЬ РАЗЛИЧНЫЕ
    |    алкХранилищеАкцизныхМарокСрезПоследних.Марка
    |ПОМЕСТИТЬ Марки
    |ИЗ
    |    РегистрСведений.алкХранилищеАкцизныхМарок.СрезПоследних(, ) КАК алкХранилищеАкцизныхМарокСрезПоследних
    |ГДЕ
    |    алкХранилищеАкцизныхМарокСрезПоследних.ОтметкаВыбытия = ИСТИНА
    |;
    |
    |////////////////////////////////////////////////////////////////////////////////
    |ВЫБРАТЬ
    |    алкХранилищеАкцизныхМарок.Регистратор КАК Регистратор,
    |    алкХранилищеАкцизныхМарок.Марка КАК Марка
    |ИЗ
    |    РегистрСведений.алкХранилищеАкцизныхМарок КАК алкХранилищеАкцизныхМарок
    |        ВНУТРЕННЕЕ СОЕДИНЕНИЕ Марки КАК Марки
    |        ПО алкХранилищеАкцизныхМарок.Марка = Марки.Марка
    |ГДЕ
    |    алкХранилищеАкцизныхМарок.Период МЕЖДУ ДАТАВРЕМЯ(2018, 1, 1, 0, 0 , 1) И ДАТАВРЕМЯ(2020, 6, 1, 0, 0, 1)
    |ИТОГИ ПО
    |    Регистратор";
    
    
    
    СчетчикДоки = 0;
    СчетчикМарки = 0;
    
    ВыборкаРегистратор = Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
    Сообщить("Окончание запроса - " + ТекущаяДата());
    
    Пока ВыборкаРегистратор.Следующий() Цикл
        НаборЗаписей = РегистрыСведений.алкХранилищеАкцизныхМарок.СоздатьНаборЗаписей();
        НаборЗаписей.Отбор.Регистратор.Установить(ВыборкаРегистратор.Регистратор);
        НаборЗаписей.Прочитать();
        сзУдаляемыеЗаписи = Новый СписокЗначений;
        ВыборкаДетальныеЗаписи = ВыборкаРегистратор.Выбрать();
        
        Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
            Для Каждого Запись Из НаборЗаписей Цикл
                Если Запись.Марка = ВыборкаДетальныеЗаписи.Марка Тогда
                    сзУдаляемыеЗаписи.Добавить(Запись);
                    СчетчикМарки = СчетчикМарки + 1;
                КонецЕсли;
            КонецЦикла;
        КонецЦикла;
        
        Для Каждого ЭлтСз Из сзУдаляемыеЗаписи Цикл
            НаборЗаписей.Удалить(ЭлтСз.Значение);
        КонецЦикла;
        
        НаборЗаписей.Записать();
        СчетчикДоки = СчетчикДоки + 1;
        //Если СчетчикДоки = 100 Тогда
        //    Прервать;
        //КонецЕсли;
        Если ТекущаяДата() > Дата(2021, 02, 03, 08, 30 , 00) Тогда
            Прервать;
        КонецЕсли;    

    КонецЦикла;
    
    Сообщить("Окончание обработки - " + ТекущаяДата());
    Сообщить("СчетчикДоки - " + СчетчикДоки);
    Сообщить("СчетчикМарки - " + СчетчикМарки);
КонецПроцедуры

Сам запрос выполняется 20 минут.
Вот для примера последний запуск.

Начало запроса - 02.02.2021 23:10:58
Окончание запроса - 02.02.2021 23:38:54
Окончание обработки - 03.02.2021 8:31:04
СчетчикДоки - 167
СчетчикМарки - 373 695
   timurhv
 
101 - 03.02.21 - 14:41
(100) Ок, как за 2 минуты записать 470тыс. элементов справочника?
   Вася Теркин
 
102 - 03.02.21 - 14:43
(0) Прямое подключение к собственной базе SQL из самой базы 1С через консоль SQL сделать сможешь, а готовую функцию пока не дают. Только что за 40 сек 13 миллионов строк РС проапдейтили. А в 1С это занимало 50 часов.
   H A D G E H O G s
 
103 - 03.02.21 - 14:44
(101) Никак, пишите в РС.
   H A D G E H O G s
 
104 - 03.02.21 - 14:45
(101) У нас алкашка, там размеры ТТН меньше.
   timurhv
 
105 - 03.02.21 - 14:50
(103) Наверное, так и сделаю и откажусь по истории РН в пользу (77). Содержимое по маркам в УПД сейчас так и пишется в независимый РС.
   TormozIT
 
106 - 03.02.21 - 14:51
Кажется готовить DELETE FROM можно так. Делаешь в консоли запросов нужный запрос к удаляемой таблице с отбором и выполняешь его с отловом запроса СУБД. Дальше в этом отловленном запросе СУБД меняешь начало "SELECT ... FROM" на "DELETE FROM dbo.<ИмяТаблицыВСУБД> FROM". Дальше выполняешь например через ADO этот запрос напрямую в СУБД. Все это некоторые консоли запросов позволяют делать не выходя из 1С.
   H A D G E H O G s
 
107 - 03.02.21 - 14:53
(105) Я бы тупо писал в справочник в многопоток в НачатьТранзакцию с отключением записи в ЖР. Если этого мало - ВнешнийИсточник данных и bulk insert по массиву подготовленных в 1С GUID и кодов марок
   timurhv
 
108 - 03.02.21 - 14:55
(107) Если внешний источник отвалится в НГ, то праздники будут испорчены :)
В многопоток я делал, но на сервере пока что только 4 ядра, не разгуляешься.
   H A D G E H O G s
 
109 - 03.02.21 - 14:57
(108) УстановитьСсылкуНового(Новый УникальныйИдентификатор) не забуть, когда в многопоток писать будешь
   Вася Теркин
 
110 - 03.02.21 - 14:58
(106) Запрещено лицензионным соглашением.
   H A D G E H O G s
 
111 - 03.02.21 - 14:58
(110) ВнешниеИсточникиДанных
   H A D G E H O G s
 
112 - 03.02.21 - 14:59
(108) Несколько лет работает обмен с wms, ниче не отвалилось
   TormozIT
 
113 - 03.02.21 - 15:00
(111) Там нет DELETE FROM. Там надо отбор по измерениям делать с одним значением.
   H A D G E H O G s
 
114 - 03.02.21 - 15:01
(113) Там есть вызов хранимых процедур :-)
   Вася Теркин
 
115 - 03.02.21 - 15:01
(108) А как разные потоки принудительно на разные рабочие процессы трехзвенки отправить? Или один рабочий процесс можно на нескольких камнях сразу крутить?
   Вася Теркин
 
116 - 03.02.21 - 15:01
Теперь можно в 8.3 новые rphost открывать по желанию?
   timurhv
 
117 - 03.02.21 - 15:02
   Вася Теркин
 
118 - 03.02.21 - 15:03
(108) Несколько фоновых - это не многопоток.
   H A D G E H O G s
 
119 - 03.02.21 - 15:05
   timurhv
 
120 - 03.02.21 - 15:05
(118) Почему нет?
   Ёпрст
 
121 - 03.02.21 - 15:58
(97) РН ? он же еще и итоги вам потом будет пересчитывать...
   timurhv
 
122 - 03.02.21 - 19:01
(121) Да, откажусь от него. Я в начале не так понял вас про структуру РС, подумал используется только Марка + Статус.
   dmpl
 
123 - 03.02.21 - 21:23
(54) А если справочник не плоский, а 2-уровневый, например. Первый уровень - "Упаковки" - ссылка на элемент, штрихкод которого реально сканирует оператор (блок, коробка, палета и т.п.), второй уровень - "Состав штрихкодов упаковок" - допустим, N элементов, в ТЧ которого содержатся коды. Допустим, до 1000 кодов в каждом элементе справочника. В ТЧ справочника "Упаковки" содержится список ссылок на справочник "Состав штрихкодов упаковок". В движениях использовать ссылки на справочник верхнего уровня (то, что реально сканирует оператор), но при необходимости можно всегда развернуть до конкретного штрихкода.
   timurhv
 
124 - 03.02.21 - 21:46
(123) Думал об этом, оператор сканирует блок, уменьшится объем в 10 раз.
Протестирую все варианты: РС независимый со строковыми измерениями, РС с записью ссылок упаковки и содержимого в ТЧ. Только в рознице марка списывается или блок (либо хэш марки добавлять в измерения, либо порядковый номер строки ТЧ справочника).
   Вася Теркин
 
125 - 04.02.21 - 10:24
(119, 120) См (115)
   timurhv
 
126 - 04.02.21 - 10:58
(125) Может
   dmpl
 
127 - 04.02.21 - 15:55
(124) На мой взгляд, не обязательно писать какой-то код в регистр. Пишется либо непосредственно штрихкод, если это неделимая упаковка, либо ссылка на упаковку со списком штрихкодов. В таком случае надо предусмотреть операцию "разборка" для упаковки, которая сделает штрихкод упаковки недоступным для дальнейшего сканирования, ну а отдельные штрихкоды упаковки наоборот станут доступны к сканированию.
  1  2

Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.