Регистры сведений. Очистка с отбором. HELP!
Имеется регистр сведений цен номенклатуры с общей заполненностью в 71 миллион записей. Существует ли способ очистки этого регистра от определенных записей с отбором например по группе номенклатуры? Какими методами это возможно реализовать?
Все возможные манипуляции приводили к отвалу обработок очистки и к сообщениям "Недостаточно памяти для получения запроса к базе данных".
База крутится на MS SQL 2014 Сервер 1С 8.3 х64.
Все возможные манипуляции приводили к отвалу обработок очистки и к сообщениям "Недостаточно памяти для получения запроса к базе данных".
База крутится на MS SQL 2014 Сервер 1С 8.3 х64.
Прикрепленные файлы:

По теме из базы знаний
Найденные решения
Остальные ответы
Подписаться на ответы
Инфостарт бот
Сортировка:
Древо развёрнутое
Свернуть все
(1) для УПП допиливал обработку поиск и замены чтобы удаляло из табличной части и подчищяло движение = мягкое перепроведение.
Что у вас подвисает и на каком этапе не понятно.
Как уже говорилось оптимизируйте запрос, запускайте в фоне несколько потоков.
Распараллеливания потоки можно периодами по месяцам, если много уменьшайте до приемлемого результата.
Что у вас подвисает и на каком этапе не понятно.
Как уже говорилось оптимизируйте запрос, запускайте в фоне несколько потоков.
Распараллеливания потоки можно периодами по месяцам, если много уменьшайте до приемлемого результата.
А если запрос порционно формировать? указывать, например, первые 1000?
И список номенклатуры по группе вы же отдельно получаете до отбора по РС?
Я к тому что у Вас должна быть ТаблицаНоменклатуры и к ней внутренним соединением накинуть регистр, а не фильтровать напрямую по таблице РС
И список номенклатуры по группе вы же отдельно получаете до отбора по РС?
Я к тому что у Вас должна быть ТаблицаНоменклатуры и к ней внутренним соединением накинуть регистр, а не фильтровать напрямую по таблице РС
регистр подчинен регистратору, надо так, в запросе можно указывать период.
Запрос = Новый Запрос;
Запрос.Текст = "
|ВЫБРАТЬ
| ЦеныНоменклатуры.Регистратор
|ИЗ
| РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры";
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
НаборЗаписей = РегистрыСведений.ЦеныНоменклатуры.СоздатьНаборЗаписей();
Пока Выборка.Следующий() Цикл
НаборЗаписей.Отбор.Регистратор.Установить(Выборка.Регистратор);
НаборЗаписей.Записать();
КонецЦикла;
Показать
Пример:
exec sp_executesql N'SEL ECT
T1.Q_001_F_000RRef,
T1.Q_001_F_004RRef,
T1.Q_001_F_005RRef,
T1.Q_001_F_001RRef,
T1.Q_001_F_002RRef,
T1.Q_001_F_003_TYPE,
T1.Q_001_F_003_RRRef,
T13.Period_,
T13.Fld7294_TYPE,
T13.Fld7294_RTRef,
T13.Fld7294_RRRef,
T13.Fld7293_,
T13.Fld7292_,
T12._Fld816RRef,
T12._Fld820,
T1.Q_001_F_007_,
T1.Q_001_F_006_,
T17._Description,
T18._Description
FR OM (SEL ECT
T4.Q_001_F_000RRef AS Q_001_F_000RRef,
T4.Q_001_F_001RRef AS Q_001_F_001RRef,
T2.Q_001_F_000RRef AS Q_001_F_002RRef,
T2.Q_001_F_001_TYPE AS Q_001_F_003_TYPE,
T2.Q_001_F_001_RRRef AS Q_001_F_003_RRRef,
T4.Q_001_F_002RRef AS Q_001_F_004RRef,
T4.Q_001_F_003RRef AS Q_001_F_005RRef,
T4.Q_001_F_004_ AS Q_001_F_006_,
T4.Q_001_F_005_ AS Q_001_F_007_
FR OM (SEL ECT DISTINCT
T3._IDRRef AS Q_001_F_000RRef,
CASE WHEN T3._Fld821 = 0x01 THEN CASE WHEN T3._Fld822RRef IS NOT NULL THEN 0x08 END ELSE 0x01 END AS Q_001_F_001_TYPE,
CASE WHEN T3._Fld821 = 0x01 THEN T3._Fld822RRef ELSE @P1 END AS Q_001_F_001_RRRef
FR OM dbo._Reference48 T3
WHERE ((T3._Fld395 = @P2))) T2
INNER JOIN (SEL ECT DISTINCT
T5.Fld7290RRef AS Q_001_F_000RRef,
T5.Fld7291RRef AS Q_001_F_001RRef,
T9._Fld1513RRef AS Q_001_F_002RRef,
CASE WHEN (T10._ParentIDRRef = @P3) THEN T9._Fld1513RRef ELSE T10._ParentIDRRef END AS Q_001_F_003RRef,
T10._Fld2563 AS Q_001_F_004_,
CASE WHEN (T10._ParentIDRRef = @P4) THEN T10._Fld2563 ELSE T11._Fld2563 END AS Q_001_F_005_
FR OM (SELECT
T8._Fld7291RRef AS Fld7291RRef,
T8._Fld7290RRef AS Fld7290RRef
FR OM (SELECT
T7._Fld7289RRef AS Fld7289RRef,
T7._Fld7290RRef AS Fld7290RRef,
T7._Fld7291RRef AS Fld7291RRef,
MAX(T7._Period) AS MAXPERIOD_
FR OM dbo._InfoRg7288 T7
WHERE (T7._Fld395 = @P5)
GROUP BY T7._Fld7289RRef,
T7._Fld7290RRef,
T7._Fld7291RRef) T6
INNER JOIN dbo._InfoRg7288 T8
ON T6.Fld7289RRef = T8._Fld7289RRef AND T6.Fld7290RRef = T8._Fld7290RRef AND T6.Fld7291RRef = T8._Fld7291RRef AND T6.MAXPERIOD_ = T8._Period
WH ERE (T8._Fld395 = @P6)) T5
LEFT OUTER JOIN dbo._Reference85 T9
ON (T5.Fld7290RRef = T9._IDRRef) AND (T9._Fld395 = @P7)
LEFT OUTER JOIN dbo._Reference145 T10
ON (T9._Fld1513RRef = T10._IDRRef) AND (T10._Fld395 = @P8)
LEFT OUTER JOIN dbo._Reference145 T11
ON (T10._ParentIDRRef = T11._IDRRef) AND (T11._Fld395 = @P9)) T4
ON 1=1) T1
LEFT OUTER JOIN dbo._Reference48 T12
ON (T1.Q_001_F_002RRef = T12._IDRRef) AND (T12._Fld395 = @P10)
LEFT OUTER JOIN (SELECT
T16._Fld7289RRef AS Fld7289RRef,
T16._Fld7291RRef AS Fld7291RRef,
T16._Fld7292 AS Fld7292_,
T16._Fld7293 AS Fld7293_,
T16._Fld7290RRef AS Fld7290RRef,
T16._Period AS Period_,
T16._Fld7294_TYPE AS Fld7294_TYPE,
T16._Fld7294_RTRef AS Fld7294_RTRef,
T16._Fld7294_RRRef AS Fld7294_RRRef
FR OM (SELECT
T15._Fld7289RRef AS Fld7289RRef,
T15._Fld7290RRef AS Fld7290RRef,
T15._Fld7291RRef AS Fld7291RRef,
MAX(T15._Period) AS MAXPERIOD_
FR OM dbo._InfoRg7288 T15
WH ERE ((T15._Fld395 = @P11)) AND (T15._Period <= @P12)
GROUP BY T15._Fld7289RRef,
T15._Fld7290RRef,
T15._Fld7291RRef) T14
INNER JOIN dbo._InfoRg7288 T16
ON T14.Fld7289RRef = T16._Fld7289RRef AND T14.Fld7290RRef = T16._Fld7290RRef AND T14.Fld7291RRef = T16._Fld7291RRef AND T14.MAXPERIOD_ = T16._Period
WH ERE (T16._Fld395 = @P13)) T13
ON (((T1.Q_001_F_000RRef = T13.Fld7290RRef) AND (T1.Q_001_F_001RRef = T13.Fld7291RRef)) AND CASE WHEN (T12._Fld821 = 0x00) THEN CASE WHEN (T1.Q_001_F_002RRef = T13.Fld7289RRef) THEN 0x01 WHEN NOT (T1.Q_001_F_002RRef = T13.Fld7289RRef) THEN 0x00 END ELSE CASE WHEN
(T12._Fld822RRef = T13.Fld7289RRef) THEN 0x01 WHEN NOT (T12._Fld822RRef = T13.Fld7289RRef) THEN 0x00 END END = 0x01)
LEFT OUTER JOIN dbo._Reference85 T17
ON (T1.Q_001_F_000RRef = T17._IDRRef) AND (T17._Fld395 = @P14)
LEFT OUTER JOIN dbo._Reference144 T18
ON (T1.Q_001_F_001RRef = T18._IDRRef) AND (T18._Fld395 = @P15)
WH ERE (T17._Marked = 0x00) AND T13.Fld7293_ = 0x01
ORDER BY (T1.Q_001_F_007_), (T1.Q_001_F_006_), (T17._Description), (T18._Description), (T1.Q_001_F_002RRef)',N'@P1 varbinary(16),@P2 numeric(10),@P3 varbinary(16),@P4 varbinary(16),@P5 numeric(10),@P6 numeric(10),@P7 numeric(10),@P8 numeric(10),@P9 numeric(10),@P10 numeric(10),@P11 numeric(10),@P12 datetime2(3),@P13 numeric(10),@P14 numeric(10),@P15 numeric(10)',0x00000000000000000000000000000000,0,0x00000000000000000000000000000000,0x00000000000000000000000000000000,0,0,0,0,0,0,0,'4018-04-16 00:00:00',0,0,0
Показать
(15) может тогда
а) создаем копию таблицы
б) заливаем в нее срез последних, при необходимости чистим (по неактуальной номенклатуре и т.п.)
в) truncate таблиц регистра сведений с ценами
г) заливаем из копии таблицы в оригинал
Единственное - определиться как кошернее создавать копию и переносить срез последних, да и тестирование и исправление на всякий случай потом прогнать. Ну и неактуальные документы установки цен как-нибудь распровести/пометить на удаление.
а) создаем копию таблицы
б) заливаем в нее срез последних, при необходимости чистим (по неактуальной номенклатуре и т.п.)
в) truncate таблиц регистра сведений с ценами
г) заливаем из копии таблицы в оригинал
Единственное - определиться как кошернее создавать копию и переносить срез последних, да и тестирование и исправление на всякий случай потом прогнать. Ну и неактуальные документы установки цен как-нибудь распровести/пометить на удаление.
(19) Если ещё актуально, можно поставить птичку для РС: "Разрешить итоги: срез последних" - далее провести реструктуризацию, если тех. платформа какой-то своей магией это сделает, дальше полная свобода - в составе Иб появится отдельная таблица итогов, можно на ее базе перезаписать основную.
Запрос = Новый Запрос;
Запрос.Текст = "
|ВЫБРАТЬ ПЕРВЫЕ 1000
| ЦеныНоменклатуры.Регистратор
|ИЗ
| РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры
| Где Номенклатура в (&ГруппаНоменклатуры)";
а что подразумевается под ценой? Конкретное число?
также параметром в запрос передать.
(20) я бы не пользовался этим способом.
Основная засада - "выбрать первые 1000" в первом запросе, во втором - так же "первые 1000", но при этом надо пропустить первые 1000, выбираемую в первом, в третьем .....
Четкого критерия все-таки нету и нагрузка на базу будет дикая.
Основная засада - "выбрать первые 1000" в первом запросе, во втором - так же "первые 1000", но при этом надо пропустить первые 1000, выбираемую в первом, в третьем .....
Четкого критерия все-таки нету и нагрузка на базу будет дикая.
(48) Наборы обрабатываемых данных не должны пересекаться. Если, например, использовать НаборЗаписей - то в каждом потоке условие отбора по ключам свое и будет блокироваться только эта группа записей (в каждом потоке своя блокировка). Вы же не будете блокировать всю таблицу.
1 - выбрать в отдельную таблицу актуальные цены номенклатуры, очистка которой будет выполняться.
2 - создать набор записей с отбором по номенклатуре. записать. очистятся все записи по этой номенклатуре.
3 - записать по этой номенклатуре актуальную цену, добавив одну запись.
Повторить для каждой номенклатуры.
Так разве не работает?
2 - создать набор записей с отбором по номенклатуре. записать. очистятся все записи по этой номенклатуре.
3 - записать по этой номенклатуре актуальную цену, добавив одну запись.
Повторить для каждой номенклатуры.
Так разве не работает?
(27)
Вообще не очень понятно, в чем проблема. Ну много записей, так это же не 71кк элементов номенклатуры.
Это 71кк записей регистра.
Выбираем из справочника номенклатуры те элементы, записи которых будем чистить.
В отдельную процедуру с параметром ТекНоменклатура вынести:
По ТекНоменклатура выполняем запрос к регистру цен - первые 1 с отбором по ТекНоменклатураи сортировкой по дате - получаем актуальную цену, которую оставляем.
Потом чистим записи по этой номенклатуре
НаборЗаписпей = РегистрыСведений.ЦеныНоменклатуры.СоздатьНаборЗаписей();
НаборЗаписпей.Отбор.Номенклатура.Установить(ТекНоменклатура);
НаборЗаписпей.Записать();
Добавить в набор запись из выборки запроса актуальной цены и записать еще раз.
Вызывать эту процедуру для каждой номенклатуры.
Выбор из 71+ миллиона записей.
Вообще не очень понятно, в чем проблема. Ну много записей, так это же не 71кк элементов номенклатуры.
Это 71кк записей регистра.
Выбираем из справочника номенклатуры те элементы, записи которых будем чистить.
В отдельную процедуру с параметром ТекНоменклатура вынести:
По ТекНоменклатура выполняем запрос к регистру цен - первые 1 с отбором по ТекНоменклатураи сортировкой по дате - получаем актуальную цену, которую оставляем.
Потом чистим записи по этой номенклатуре
НаборЗаписпей = РегистрыСведений.ЦеныНоменклатуры.СоздатьНаборЗаписей();
НаборЗаписпей.Отбор.Номенклатура.Установить(ТекНоменклатура);
НаборЗаписпей.Записать();
Добавить в набор запись из выборки запроса актуальной цены и записать еще раз.
Вызывать эту процедуру для каждой номенклатуры.
(35) УНФ у меня под рукой нет, поэтому примерный код такой
Запрос = Новый Запрос;
Запрос.Текст = "
|ВЫБРАТЬ
| Спр.Ссылка
|ИЗ
| Справочник.Номенклатура КАК Спр
| Где Ссылка в (&ГруппаНоменклатуры)";
...
Выборка = Запрос.Выполнить().Выбрать();
НужнаАктуальнаяЦена = Истина;
Пока Выборка.Следующий() Цикл
ОчиститьЗаписиРегистра(ТекНоменклатура,НужнаАктуальнаяЦена );
КонецЦикла;
Процедура ОчиститьЗаписиРегистра(ТекНоменклатура,НужнаАктуальная)
Если НужнаАктуальная Тогда
Запрос = Новый Запрос;
Запрос.Текст = "
|ВЫБРАТЬ ПЕРВЫЕ 1
| *
|ИЗ
| РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры
| Где Номенклатура = &ТекНоменклатура
|Упорядочить По Период Убыв";
...
Выборка = Запрос.Выполнить().Выбрать();
КонецЕсли;
НаборЗаписпей = РегистрыСведений.ЦеныНоменклатуры.СоздатьНаборЗаписей();
НаборЗаписпей.Отбор.Номенклатура.Установить(ТекНоменклатура);
НаборЗаписпей.Записать();
Если НужнаАктуальная И Выборка.Следующий() Тогда
НовЗапись = НаборЗаписей.Добавить();
ЗаполнитьЗначенияСвойств(НовЗапись,Выборка);
НаборЗаписей.Записать();
КонецЕсли;
КонецПроцедуры
Показать
в обработке "Поиск и замена реквизитов для УФ (с обработкой табличных частей)" есть возможность задавать отборы запросом ну или списком по полям фильтрации
Это я к тому, что я использовал эту обработку на регистрах сведений с кол-во записей от 10 млн. до 200+ млн. записей
и она неплохо чистит - главное голова не болит, что не тот отбор и все пропало. Отобрал 10 000 записей - удалить и т.д.
и так неспешно и вдумчимо, в процессе других дел, можно решать подобные задачи без костылей и промахов.
Это я к тому, что я использовал эту обработку на регистрах сведений с кол-во записей от 10 млн. до 200+ млн. записей
и она неплохо чистит - главное голова не болит, что не тот отбор и все пропало. Отобрал 10 000 записей - удалить и т.д.
и так неспешно и вдумчимо, в процессе других дел, можно решать подобные задачи без костылей и промахов.
(32) Произвольным запросом отбор делать надо(там кнопочка есть расширенный отбор или что-то вроде) и ставить ПЕРВЫЕ 5000 или Первые 10 000
Эта обработка выводит отобранные записи в табличную часть и ясен пень без ПЕРВЫЕ при попытке втиснуть в ТЧ отобранные по группе миллионы будет падение
Эта обработка выводит отобранные записи в табличную часть и ясен пень без ПЕРВЫЕ при попытке втиснуть в ТЧ отобранные по группе миллионы будет падение
(43) Вам предложили способы решения средствами 1С.
Но... не в коня корм =)
Ставить же награду за тему, а потом выплачивать ее себе за пустые сообщения - это как минимум не красиво.
Если бы вы решили проблему по своему и потом написали способ решения - и на это сообщение выплатить награду, это одно, а так как сделали сейчас - фу так делать.
Но... не в коня корм =)
Ставить же награду за тему, а потом выплачивать ее себе за пустые сообщения - это как минимум не красиво.
Если бы вы решили проблему по своему и потом написали способ решения - и на это сообщение выплатить награду, это одно, а так как сделали сейчас - фу так делать.
регистр сведений периодический? почему отбор по периоду исключен?
вытащите запросом просто структуру данных "Номенклатура" "Кол-во записей в РС" даже можно с отбором по 1 номенклатуре, сколько времени займет? только сразу ко-во считайте что бы все другие поля не тянуть.
вытащите запросом просто структуру данных "Номенклатура" "Кол-во записей в РС" даже можно с отбором по 1 номенклатуре, сколько времени займет? только сразу ко-во считайте что бы все другие поля не тянуть.
(57)Посмотрите за какой период сколько данных, с какого периода у вас база с 2000 года? пусть за год 2000 - 2001 сколько записей ? они все не нудны? Выбрать их набором по отбору даты и очистить не перебирая. Или на самом деле удалить все и проставить цены одним документом ( или обработкой ) на дату. У вас вообще какая конченая цель? удалить старые цены из регистра независимо от того были по ним продажи по этим ценам или нет? или что?
Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот