Имя: Пароль:
1C
1С v8
Как быстрее всего удалить много записей средствами MS SQL
0 Genayo
 
30.08.17
10:06
Платформа 1С 8.2, в базе есть примерно 68 млн. документов одного вида, без табличных частей, около 35 млн. из них надо удалить с отбором по дате меньше определенной, ссылочная целостность не важна. Время простоя базы ограничено. Понятно, что средствами 1С быстро это сделать нереально. Как сделать это максимально быстро? Удалять в одной транзакции или бить на несколько, если на несколько, то как определить оптимальный с точки зрения скорости размер порции?
14 Черный маклер
 
30.08.17
10:40
(0) порция = 1 месяц
15 Genayo
 
30.08.17
10:43
(14) Точно быстрее будет, чем одной транзакцией? По месяцам это будет 15 транзакций, запустил на тестовой, сравню время с удалением одной транзакцией. Но интересно не только из опыта, но и теоретически понять как быстрее всего решить такую задачу.
16 SSSSS_AAAAA
 
30.08.17
10:44
(13)Если хочется быстрее, то надо нарисовать процедуру по удалению порциями с транзакциями для каждой порции. В которой, может быть, и создавать временно нужный индекс. Если нет подходящего. И размер порции подобрать эмпирически.  И эту процедуру запускать через ADO.
17 Черный маклер
 
30.08.17
10:46
(15) когда в одной транзакции - не знаешь умер процесс или шевелится и ресурсов много надо.
а когда квантами - сразу видно, что процесс идет:)

а движения почему не удаляешь ?
18 Genayo
 
30.08.17
10:50
(17) Конфигурация нетиповая, движения только по одному регистру накопления с одним регистратором, почистил раньше уже.
19 Господин ПЖ
 
30.08.17
10:52
база большая?

в рабочей базе - truncate table, а потом из копии в нее bulk insert нужного
20 lodger
 
30.08.17
10:52
DELETE table_or_view
FROM table_sources
WHERE search_condition
21 GANR
 
30.08.17
10:55
(0) Быстрое   в ы б о р о ч н о е   удаление большого количества записей из раздутого регистра!? Нет сынок, это фантастика - намучились вволю уже. Если подскажете по-настоящему быстрый способ буду благодарен. (20) точно не быстро.
22 spock
 
30.08.17
10:59
(0)Средствами скуля разделить на секции и потом уже секции грохать. В конце собрать все, как было.
23 Genayo
 
30.08.17
11:06
(19) Размер удаляемой таблицы 15 GB, с учетом включенного сжатия на SQL.Это много?
24 Genayo
 
30.08.17
11:06
(20) Спасибо, кэп.
25 Genayo
 
30.08.17
11:07
(21) Регистр пока не рассматриваем, только документы с отбором по дате меньше.
26 Господин ПЖ
 
30.08.17
11:08
рой в сторону (19) - это не журналируемые операции заточенные на большие разовые объемы данных
27 GANR
 
30.08.17
11:10
(25) тем более - на объектные данные еще и ссылки могут быть
28 GANR
 
30.08.17
11:10
(25) Вы уверены, что (27) исключено?
29 GANR
 
30.08.17
11:30
(24) delete - фигня по скорости, пробовал уже. Я бы (19) попробовал - вот bulk insert может ускорить.
30 ptiz
 
30.08.17
11:35
(19) "а потом из копии в нее bulk insert нужного"
А как сделать bulk insert из таблицы SQL? Это команда вроде только с файлами работает?
31 lodger
 
30.08.17
11:37
а так?
1) select * into [destinationTable] from [sourceTable] where search_condition
2) подменить sourceTable на destinationTable.
3) похерить sourceTable.
32 ptiz
 
30.08.17
11:39
(31) Индексы же потеряются
33 Genayo
 
30.08.17
11:40
(28) Уверен. Кроме регистра накопления, который уже очищен, ссылок на этот документ нет.
34 Genayo
 
30.08.17
11:42
(30) Ну в теории можно выгрузить в файл - из файла bulk insert, только не факт, что по времени это быстрее будет.
35 lodger
 
30.08.17
11:43
(32) + (33) = пофиг.
36 Господин ПЖ
 
30.08.17
11:44
(30) ну можно обойтись insert into
37 Господин ПЖ
 
30.08.17
11:47
можно через ssis, если он доступен
38 ptiz
 
30.08.17
11:47
(36) Я у себя так и делаю - медленно выходит :(
Тоже большие таблицы
39 wayrarer
 
30.08.17
11:55
Вариант - ПодключитьОбработчикОжидания. Интервал вызова и количество документов на удаление обработка читает каждый раз из регистра сведений - можно подбирать нагрузку, чтоб и процесс шел, и пользователи работали. Иногда только так выкручиваемся, когда надо изменять большие объемы в фоновом режиме.
40 drumandbass
 
30.08.17
12:06
(0) Поставь платформу 8.3 ))) попробуй как удаляет. (офигеешь от разницы в скорости)
Попробуй грохнуть в файловом варианте.
а. так то в сиквеле 2 варианта
1. Выгрузка данных в промежуточную таблицу (те что надо оставить) truncate потом таблицы. и те что оставил заливаешь обратно
2. delete from tab where tab.date < date
41 Genayo
 
30.08.17
12:07
(39) Фоновый режим не вариант, есть 3-4 часа допустимого простоя системы, надо в них уложиться. Пока укладываюсь, но на грани, что-то пойдет не так и проблемы обеспечены...
42 Genayo
 
30.08.17
12:12
(40) Не будет платформой быстрей, чем через SQL всеравно, даже пробовать не буду.
43 Вафель
 
30.08.17
12:14
delete from можно делать пока все работают
44 Господин ПЖ
 
30.08.17
12:15
(43) смотря какие блокировки скуль наложит
45 Вафель
 
30.08.17
12:16
Эскалацию можно отключить на время
46 Genayo
 
30.08.17
12:20
(43) Можно, но в этой задаче не нужно :) Да и потом статистики всеравно пересчитывать, можно словить тормоза на неактуальных статистиках.
47 ptiz
 
30.08.17
12:20
(41) На SSD и простой delete за час справится с такой таблицей.
48 Genayo
 
30.08.17
12:25
(47) Да, рабочий сервер на SSD да и памяти на скуле побольше, надеюсь раза в 2 быстрее, чем на тестовом будет. Но нет пределов совершенству :)
49 Вафель
 
30.08.17
12:26
(46) в данном случае статистика не решает. статистика решает при добавлении
50 assasu
 
30.08.17
12:26
(10)если эти 68 млн Г копились столько лет  и никому не мешали  - ничего не мешает их так же потихоньку удалять.
каждый день по 100 тыс и все ...
51 ptiz
 
30.08.17
12:29
Кстати - да, работу останавливать совсем не обязательно при удалении частями.
52 Genayo
 
30.08.17
13:13
(49) Ну да, если при работе пользователей удалять много записей, кривая статистика на работе этих пользователей может сказаться отрицательно.
53 lodger
 
30.08.17
13:20
вот мы и вернулись к (20)
только допишем
DELETE TOP (ВашеЛюбимоеЧисло)
FROM ВашаТаблица
WHERE ДатаДокумента < 'НужнаяДата';

теперь запускаем это периодично, когда нагрузка на систему ниже определенной психологической отметки.
54 vis_tmp
 
30.08.17
13:20
(10)А удалял командой "УдалитьОбъекты()" ?
55 Genayo
 
30.08.17
13:26
(53) Это решение совсем другой задачи :)
56 lodger
 
30.08.17
13:28
(55) вам шашечки или ехать?
57 vis_tmp
 
30.08.17
13:30
Мне уточнить у автора
58 Genayo
 
30.08.17
13:32
(54) Так намного быстрее будет? Нет, по одному удалял.
59 VS-1976
 
30.08.17
13:33
Если пользователи не работают, то можно грохнуть перед удалением все лишние индексы ( сильно ускорит, так как в индексах так же проставляется пометка удаления ), оставить только нужный для отбора.

Для MS SQL советуют использовать SET NO_BROWSETABLE ON
https://support.microsoft.com/ru-ru/help/885146/additional-information-about-the-for-browse-option-and-the-no-browseta

Обсуждение
http://www.sql.ru/forum/199345/udalenie-zapisey-iz-bolshoy-tablicy
60 vis_tmp
 
30.08.17
13:33
(58)Да, попробуй
61 Genayo
 
30.08.17
13:35
(56) Я принял вашу информацию к сведению :)
62 Genayo
 
30.08.17
13:42
(59) А вот это интересно, попробую. Там еще хинт TABLOCK попробовать советуют. А SET NO_BROWSETABLE ON можно через ADODB сделать, или только в менеджмент студии?
63 VS-1976
 
30.08.17
13:51
(62) Думаю можно. Там как бы на сессию это действует скорее всего
64 braslavets
 
30.08.17
15:01
(0)
Выбери во временную таблицу, те документы, которые нужно оставить, сделай truncate основной, вставь из временной таблицы обратно.
65 VS-1976
 
30.08.17
15:31
(64) Выборка может быть медленной ( если объём ), а потом ещё и вставка ( индекс так же будет вставляться ). Проще как я описал. И после удаления пересоздать удалённые индексы ( можно уже руками, предварительно сделав дефрагментацию ).
66 Genayo
 
30.08.17
16:00
(59) Не ускорили советы по ссылкам, к сожалению. 2 млн записей удаляется 8 минут.
67 ptiz
 
30.08.17
16:23
(66) WITH TABLOCK тоже не ускорил?
68 Господин ПЖ
 
30.08.17
16:29
>2 млн записей удаляется 8 минут.

нормальный результат
69 Genayo
 
30.08.17
16:35
(68) Ну, скажем так, приемлемый. Нормальный было бы все 35 млн за 8 минут. Но жить с этим можно, да.
70 Genayo
 
30.08.17
16:36
(67) Нет, а вот WITH (TABLOCKX) процентов на 10 ускорил.
71 VS-1976
 
30.08.17
18:12
(70) Ты все индексы удалил кроме одного где Дата + Ссылка ( Дата в индексе должна быть первой )?
Можно ещё статистику подсобрать после удаления индексов приблизительную. И сообщи какие у тебя условия в where. И зачем тебе транзакция в этом действии ( ты хочешь чтобы пользователи в этот момент работали? )
72 МихаилМ
 
30.08.17
18:30
(15) "2 млн записей удаляется 8 минут.

нормальный результат"


нормальный результат 15 летней давности когда запись 20 МБ/сек была нормальной. сейчас ~30 сукунд.
73 МихаилМ
 
30.08.17
18:41
ошибся .
(72) относится к (68)
74 МихаилМ
 
30.08.17
19:19
вопрос поставлен в (0)
некорректно


тк существуют две ситуации  1) избыток вычислительных ресурсов

2 ) недостаток.


большинство успешных решений для случая 1)
будут не успешными для случая 2)
75 Genayo
 
30.08.17
20:01
(71) Не, индексы не удалял. Транзакция для надежности, вдруг что-нибудь пойдет не так. Хотя, наверное можно и без транзакции, если подумать. Кстати, в менеджмент студии Delete выполняется по умолчанию в транзакции или нет?
76 Genayo
 
30.08.17
20:06
(72) Замедление из-за перестроения индексов в общем нормальное предположение, склонен с ним согласится.
Что касается ресурсов вопрос интересный конечно, недостатка ресурсов нет однозначно, насчет избытка не уверен...
77 VS-1976
 
30.08.17
20:41
(75) Нужно удалить индексы. Они удаляются пометкой удаления без физического удаления. Транзакция создаёт лишний объём работы, да и не нужна она в общем-то ( актуально для oracle с его undotablespace. Скорее всего для M$ так же хотя и не уверен, так как M$ всё равно в лог всё запишет и восстановление идёт из него если что. Транзакция влияет на блокировки ). DELETE работает без транзакции но в лог попадает разумеется, возможно режим логирования SIMPLE уменьшит объём логов ( не уверен. Надеюсь log файл на отдельном диске ). После удаления просто командой DML - CREATE INDEX создаёшь удалённые индексы. Время должно уменьшиться серьёзно, особенно если индексов много, да и индексные файлы сами по себе большие из-за большой таблицы. При относительно маленьком объёме оперативки может происходить много I/O.
78 VS-1976
 
30.08.17
20:47
(77) Затупил CREATE INDEX это команда семейства DDL https://ru.wikipedia.org/wiki/Data_Definition_Language
79 МихаилМ
 
30.08.17
20:49
(76) из Ваших вопросов ясно, что у Вас не понимания эксплуатации субд.
поэтому пользуйтесь простыми методами. Вам тут не расскажут
главы из руководства субд про массовые вставки , удаления обновления.


уточню (74) если с таблицами не работают реальные
много пользователей (olap) то одни варианты  , иначе - другие.
80 VS-1976
 
30.08.17
20:51
(79) OLTP https://ru.wikipedia.org/wiki/OLTP а не OLAP
81 VS-1976
 
30.08.17
20:55
(77) + Приведи что в конструкции после WHERE. Если удаление диапазонами, то оставь 1 индекс, где поле Дата будет первым полем и количество полей в индексе минимально.
82 МихаилМ
 
30.08.17
21:06
(80) извините . написал коряво, НО правильно . читайте внимательней
83 МихаилМ
 
30.08.17
21:08
(77)если с таблицей работают люди, то удаление индексов - преступление.
84 VS-1976
 
30.08.17
21:13
(83) в (0) Время простоя базы ограничено
в (41) есть 3-4 часа допустимого простоя системы, надо в них уложиться.
85 VS-1976
 
30.08.17
21:16
(82) OLAP это аналитика, для неё обычно данные переносятся в другое хранилище, да и нагрузка не такая как на OLTP, так как данные в OLAP обычно агрегируются.
86 VS-1976
 
30.08.17
21:18
И да после удаления такого объёма нужно как минимум перестраивать индексы данной таблицы + статистику для ускорения доступа ( запросы )
87 Genayo
 
31.08.17
07:50
(77) Да, удаление индексов помогло - оставил только кластерный и по периоду, и вместо 8 минут удаление прошло за минуту примерно. Скрипты на удаление и создание индексов очень просто делаются из менеджмент студии, создание индексов делается достаточно быстро.
88 Genayo
 
31.08.17
07:53
(79) Да, вы правы, эксплуатацией СУБД занимается отдельный человек, просто для себя интересно чуть глубже понимать механизмы. Главы пересказывать не надо, надо просто подтолкнуть в правильном направлении :)
89 VS-1976
 
31.08.17
08:33
(87) Если удаление по периоду, то кластерный можно так же грохнуть и потом воссоздать
90 Genayo
 
31.08.17
08:54
(89) Можно, но и так вроде неплохо. Сейчас протестирую удаление одним запросом, замерю время создания индексов, и будет понятно стоит ли дальше оптимизировать.
91 ptiz
 
31.08.17
10:38
(90) Только что делать, если таблиц - десяток. Руками с ума сойдешь индексы удалять/пересоздавать :(
А то мне предстоит скоро таблицы на сотни миллионов записей чистить.
92 VS-1976
 
31.08.17
11:54
(91) Да скрипт готовишь используя SQL Server Management Studio. Можно ещё программно из 1С скрипт подготовить, используя ПолучитьСтруктуруХраненияБазыДанных
93 Genayo
 
31.08.17
12:15
(90) По итогу - 30 млн записей удалились за 16 минут, 28 минут на пересоздание индексов. Дальше оптимизировать смысла не вижу.
94 Genayo
 
31.08.17
12:18
(92) Ну да, для одного индекса получить скрипт на drop/create, дальше по аналогии для всех нужных индексов делаешь, и через ADODB запускаешь итоговый скрипт.
95 vis_tmp
 
31.08.17
15:07
(94)А (54) не попробовал?
96 VS-1976
 
31.08.17
15:15
(95) Пятница только завтра... или ты решил со среды начать народ подогревать?
97 vis_tmp
 
31.08.17
15:40
Мне правда интересно.
Я удалял много объектов этой одной командой.
98 Genayo
 
31.08.17
15:41
(95) Порциями по 1 млн? Оно не подохнет по памяти?
99 vis_tmp
 
31.08.17
15:42
(98)Не пробовал, значит
100 vis_tmp
 
31.08.17
15:42
100
101 Вафель
 
31.08.17
15:44
А говорят индекс можно просто отключить на время, а не пересоздавать
102 Вафель
 
31.08.17
15:44
ALTER INDEX IX_Employee_OrganizationLevel_OrganizationNode ON HumanResources.Employee
DISABLE;
103 Вафель
 
31.08.17
15:45
или даже так
ALTER INDEX ALL ON HumanResources.Employee
104 Вафель
 
31.08.17
15:45
105 Genayo
 
31.08.17
16:06
(101) Так при удалении такого количества записей всеравно надо будет скорее всего реиндексацию и дефрагментацию индексов делать, так почему бы и не пересоздать? Но попробую и такой вариант, спасибо.
106 Genayo
 
31.08.17
16:10
(99) Тоесть ты реально удалял миллион объектов через УдалитьОбъекты?
107 Вафель
 
31.08.17
16:15
(105) Кода меньше просто, не нужно думать какие индексы есть ибо ALL
108 Вафель
 
31.08.17
16:16
Ну и включение индекса - это и есть Rebuild
109 Йохохо
 
31.08.17
16:16
(105) не будет операций по обновлению индекса во время удаления
110 ptiz
 
31.08.17
16:25
(108) О! Спасибо, пригодится.
111 Genayo
 
31.08.17
16:26
(109) Я имею в виду после удаления это сделать надо будет.
112 VS-1976
 
31.08.17
16:44
(106) УдалитьОбъекты удаляет родителькую запись  + подчинённые записи таблиц + движения делая запросы вида DELETE в базу. Скорость удаления только замедлится ( на сколько я понимаю ты удаляешь не все данные, а только чтобы почистить к примеру движения? Не понимаю настойчивость товарища с УдалитьОбъекты, но уже не смешно...
113 VS-1976
 
31.08.17
18:42
(112) + на каждый документ будет генерироваться несколько DELETE, если документов к примеру миллион то запросов будет несколько миллионов. Там только на сетевую активность между 1С и базой данных уйдёт куча времени. Чтобы получить массив ссылок нужно ещё используя отбор грузануть эти ссылки ( пусть даже и будет чтение только из индекса ). И так как индексы не отключены / удалены в том числе в подчинённых таблицах и регистрах то удаление будет в индексах возрастёт многократно.

PS: Совет тому кто такое советует бездумно. Ты лучше в пятницу давай такие советы, подумают что юморишь...
Оптимист верит, что мы живем в лучшем из миров. Пессимист боится, что так оно и есть.