|   |   | 
| 
 | Как быстрее всего удалить много записей средствами 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: Совет тому кто такое советует бездумно. Ты лучше в пятницу давай такие советы, подумают что юморишь... | 
| Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |