Как быстрее всего удалить много записей средствами MS SQL #803923


#0 by Genayo
Платформа 1С 8.2, в базе есть примерно 68 млн. документов одного вида, без табличных частей, около 35 млн. из них надо удалить с отбором по дате меньше определенной, ссылочная целостность не важна. Время простоя базы ограничено. Понятно, что средствами 1С быстро это сделать нереально. Как сделать это максимально быстро? Удалять в одной транзакции или бить на несколько, если на несколько, то как определить оптимальный с точки зрения скорости размер порции?
#0 by Genayo
Платформа 1С 8.2, в базе есть примерно 68 млн. документов одного вида, без табличных частей, около 35 млн. из них надо удалить с отбором по дате меньше определенной, ссылочная целостность не важна. Время простоя базы ограничено. Понятно, что средствами 1С быстро это сделать нереально. Как сделать это максимально быстро? Удалять в одной транзакции или бить на несколько, если на несколько, то как определить оптимальный с точки зрения скорости размер порции?
#1 by r_i_n_i_k
Если в скуле это одна таблица, то truncate. За секунду грохнет все записи
#2 by Timon1405
>>надо удалить с отбором
#3 by Genayo
truncate для таблиц итогов хорошо, в этом случае не подойдет.
#4 by r_i_n_i_k
а тогда не подойдет, она всю таблицу грохнет. Тогда delete с условием
#5 by Genayo
Один из вариантов, да. Но и тут можно либо одной транзакцией сделать, либо несколькими. Как быстрее, вот в чем вопрос.
#6 by vis_tmp
А 1С за какое время у тебя их удаляет?
#7 by H A D G E H O G s
за бесконечное.
#8 by Вафель
Самое сложное - это распровести
#9 by Genayo
В контексте данной задачи это не важно.
#10 by Genayo
Я попробовал удалить 100 тыс, около 30 минут заняло. Ну его нафик.
#11 by SSSSS_AAAAA
Значит уменьшайте до 50-30-20-10-5-1 тысяч и опытным путем находите подходящий размер порции. Индексы именно для такого удаления есть? Или просто "какие-то индексы" есть? План запроса на удаление смотрели?
#12 by SSSSS_AAAAA
Я имел в виду удаление средствами sql, а не 1с. Рисуете запрос на  удаление в цикле и вперед.
#13 by Genayo
Это я про средствами 1С, такто через ADODB одной транзакцией за 2 часа удалилось, но хочется еще быстрее :) Индексы специальные для этого разового удаления делать както не очень хочется.
#14 by Черный маклер
порция = 1 месяц
#15 by Genayo
Точно быстрее будет, чем одной транзакцией? По месяцам это будет 15 транзакций, запустил на тестовой, сравню время с удалением одной транзакцией. Но интересно не только из опыта, но и теоретически понять как быстрее всего решить такую задачу.
#16 by SSSSS_AAAAA
Если хочется быстрее, то надо нарисовать процедуру по удалению порциями с транзакциями для каждой порции. В которой, может быть, и создавать временно нужный индекс. Если нет подходящего. И размер порции подобрать эмпирически.  И эту процедуру запускать через ADO.
#17 by Черный маклер
когда в одной транзакции - не знаешь умер процесс или шевелится и ресурсов много надо. а когда квантами - сразу видно, что процесс идет:) а движения почему не удаляешь ?
#18 by Genayo
Конфигурация нетиповая, движения только по одному регистру накопления с одним регистратором, почистил раньше уже.
#19 by Господин ПЖ
база большая? в рабочей базе - truncate table, а потом из копии в нее bulk insert нужного
#20 by lodger
#21 by GANR
Быстрое   в ы б о р о ч н о е   удаление большого количества записей из раздутого регистра!? Нет сынок, это фантастика - намучились вволю уже. Если подскажете по-настоящему быстрый способ буду благодарен. точно не быстро.
#22 by spock
Средствами скуля разделить на секции и потом уже секции грохать. В конце собрать все, как было.
#23 by Genayo
Размер удаляемой таблицы 15 GB, с учетом включенного сжатия на SQL.Это много?
#24 by Genayo
Спасибо, кэп.
#25 by Genayo
Регистр пока не рассматриваем, только документы с отбором по дате меньше.
#26 by Господин ПЖ
рой в сторону - это не журналируемые операции заточенные на большие разовые объемы данных
#27 by GANR
тем более - на объектные данные еще и ссылки могут быть
#28 by GANR
Вы уверены, что исключено?
#29 by GANR
delete - фигня по скорости, пробовал уже. Я бы попробовал - вот bulk insert может ускорить.
#30 by ptiz
"а потом из копии в нее bulk insert нужного" А как сделать bulk insert из таблицы SQL? Это команда вроде только с файлами работает?
#31 by lodger
а так? 1) select * into [destinationTable] from [sourceTable] where search_condition 2) подменить sourceTable на destinationTable. 3) похерить sourceTable.
#32 by ptiz
Индексы же потеряются
#33 by Genayo
Уверен. Кроме регистра накопления, который уже очищен, ссылок на этот документ нет.
#34 by Genayo
Ну в теории можно выгрузить в файл - из файла bulk insert, только не факт, что по времени это быстрее будет.
#35 by lodger
+ = пофиг.
#36 by Господин ПЖ
ну можно обойтись insert into
#37 by Господин ПЖ
можно через ssis, если он доступен
#38 by ptiz
Я у себя так и делаю - медленно выходит :( Тоже большие таблицы
#39 by wayrarer
Вариант - ПодключитьОбработчикОжидания. Интервал вызова и количество документов на удаление обработка читает каждый раз из регистра сведений - можно подбирать нагрузку, чтоб и процесс шел, и пользователи работали. Иногда только так выкручиваемся, когда надо изменять большие объемы в фоновом режиме.
#40 by drumandbass
Поставь платформу 8.3 ))) попробуй как удаляет. (офигеешь от разницы в скорости) Попробуй грохнуть в файловом варианте. а. так то в сиквеле 2 варианта 1. Выгрузка данных в промежуточную таблицу (те что надо оставить) truncate потом таблицы. и те что оставил заливаешь обратно 2. delete from tab where tab.date < date
#41 by Genayo
Фоновый режим не вариант, есть 3-4 часа допустимого простоя системы, надо в них уложиться. Пока укладываюсь, но на грани, что-то пойдет не так и проблемы обеспечены...
#42 by Genayo
Не будет платформой быстрей, чем через SQL всеравно, даже пробовать не буду.
#43 by Вафель
delete from можно делать пока все работают
#44 by Господин ПЖ
смотря какие блокировки скуль наложит
#45 by Вафель
Эскалацию можно отключить на время
#46 by Genayo
Можно, но в этой задаче не нужно :) Да и потом статистики всеравно пересчитывать, можно словить тормоза на неактуальных статистиках.
#47 by ptiz
На SSD и простой delete за час справится с такой таблицей.
#48 by Genayo
Да, рабочий сервер на SSD да и памяти на скуле побольше, надеюсь раза в 2 быстрее, чем на тестовом будет. Но нет пределов совершенству :)
#49 by Вафель
в данном случае статистика не решает. статистика решает при добавлении
#50 by assasu
если эти 68 млн Г копились столько лет  и никому не мешали  - ничего не мешает их так же потихоньку удалять. каждый день по 100 тыс и все ...
#51 by ptiz
Кстати - да, работу останавливать совсем не обязательно при удалении частями.
#52 by Genayo
Ну да, если при работе пользователей удалять много записей, кривая статистика на работе этих пользователей может сказаться отрицательно.
#53 by lodger
вот мы и вернулись к только допишем теперь запускаем это периодично, когда нагрузка на систему ниже определенной психологической отметки.
#54 by vis_tmp
А удалял командой "УдалитьОбъекты" ?
#55 by Genayo
Это решение совсем другой задачи :)
#56 by lodger
вам шашечки или ехать?
#57 by vis_tmp
Мне уточнить у автора
#58 by Genayo
Так намного быстрее будет? Нет, по одному удалял.
#59 by VS-1976
Если пользователи не работают, то можно грохнуть перед удалением все лишние индексы ( сильно ускорит, так как в индексах так же проставляется пометка удаления ), оставить только нужный для отбора. Для MS SQL советуют использовать SET NO_BROWSETABLE ON Обсуждение
#60 by vis_tmp
Да, попробуй
#61 by Genayo
Я принял вашу информацию к сведению :)
#62 by Genayo
А вот это интересно, попробую. Там еще хинт TABLOCK попробовать советуют. А SET NO_BROWSETABLE ON можно через ADODB сделать, или только в менеджмент студии?
#63 by VS-1976
Думаю можно. Там как бы на сессию это действует скорее всего
#64 by braslavets
Выбери во временную таблицу, те документы, которые нужно оставить, сделай truncate основной, вставь из временной таблицы обратно.
#65 by VS-1976
Выборка может быть медленной ( если объём ), а потом ещё и вставка ( индекс так же будет вставляться ). Проще как я описал. И после удаления пересоздать удалённые индексы ( можно уже руками, предварительно сделав дефрагментацию ).
#66 by Genayo
Не ускорили советы по ссылкам, к сожалению. 2 млн записей удаляется 8 минут.
#67 by ptiz
WITH TABLOCK тоже не ускорил?
#68 by Господин ПЖ
>2 млн записей удаляется 8 минут. нормальный результат
#69 by Genayo
Ну, скажем так, приемлемый. Нормальный было бы все 35 млн за 8 минут. Но жить с этим можно, да.
#70 by Genayo
Нет, а вот WITH (TABLOCKX) процентов на 10 ускорил.
#71 by VS-1976
Ты все индексы удалил кроме одного где Дата + Ссылка ( Дата в индексе должна быть первой )? Можно ещё статистику подсобрать после удаления индексов приблизительную. И сообщи какие у тебя условия в where. И зачем тебе транзакция в этом действии ( ты хочешь чтобы пользователи в этот момент работали? )
#72 by МихаилМ
"2 млн записей удаляется 8 минут. нормальный результат 15 летней давности когда запись 20 МБ/сек была нормальной. сейчас ~30 сукунд.
#73 by МихаилМ
ошибся . относится к
#74 by МихаилМ
вопрос поставлен в некорректно тк существуют две ситуации  1) избыток вычислительных ресурсов 2 ) недостаток. большинство успешных решений для случая 1) будут не успешными для случая 2)
#75 by Genayo
Не, индексы не удалял. Транзакция для надежности, вдруг что-нибудь пойдет не так. Хотя, наверное можно и без транзакции, если подумать. Кстати, в менеджмент студии Delete выполняется по умолчанию в транзакции или нет?
#76 by Genayo
Замедление из-за перестроения индексов в общем нормальное предположение, склонен с ним согласится. Что касается ресурсов вопрос интересный конечно, недостатка ресурсов нет однозначно, насчет избытка не уверен...
#77 by VS-1976
Нужно удалить индексы. Они удаляются пометкой удаления без физического удаления. Транзакция создаёт лишний объём работы, да и не нужна она в общем-то ( актуально для oracle с его undotablespace. Скорее всего для M$ так же хотя и не уверен, так как M$ всё равно в лог всё запишет и восстановление идёт из него если что. Транзакция влияет на блокировки ). DELETE работает без транзакции но в лог попадает разумеется, возможно режим логирования SIMPLE уменьшит объём логов ( не уверен. Надеюсь log файл на отдельном диске ). После удаления просто командой DML - CREATE INDEX создаёшь удалённые индексы. Время должно уменьшиться серьёзно, особенно если индексов много, да и индексные файлы сами по себе большие из-за большой таблицы. При относительно маленьком объёме оперативки может происходить много I/O.
#78 by VS-1976
Затупил CREATE INDEX это команда семейства DDL
#79 by МихаилМ
из Ваших вопросов ясно, что у Вас не понимания эксплуатации субд. поэтому пользуйтесь простыми методами. Вам тут не расскажут главы из руководства субд про массовые вставки , удаления обновления. уточню если с таблицами не работают реальные много пользователей (olap) то одни варианты  , иначе - другие.
#80 by VS-1976
OLTP а не OLAP
#81 by VS-1976
+ Приведи что в конструкции после WHERE. Если удаление диапазонами, то оставь 1 индекс, где поле Дата будет первым полем и количество полей в индексе минимально.
#82 by МихаилМ
извините . написал коряво, НО правильно . читайте внимательней
#83 by МихаилМ
если с таблицей работают люди, то удаление индексов - преступление.
#84 by VS-1976
в Время простоя базы ограничено в есть 3-4 часа допустимого простоя системы, надо в них уложиться.
#85 by VS-1976
OLAP это аналитика, для неё обычно данные переносятся в другое хранилище, да и нагрузка не такая как на OLTP, так как данные в OLAP обычно агрегируются.
#86 by VS-1976
И да после удаления такого объёма нужно как минимум перестраивать индексы данной таблицы + статистику для ускорения доступа ( запросы )
#87 by Genayo
Да, удаление индексов помогло - оставил только кластерный и по периоду, и вместо 8 минут удаление прошло за минуту примерно. Скрипты на удаление и создание индексов очень просто делаются из менеджмент студии, создание индексов делается достаточно быстро.
#88 by Genayo
Да, вы правы, эксплуатацией СУБД занимается отдельный человек, просто для себя интересно чуть глубже понимать механизмы. Главы пересказывать не надо, надо просто подтолкнуть в правильном направлении :)
#89 by VS-1976
Если удаление по периоду, то кластерный можно так же грохнуть и потом воссоздать
#90 by Genayo
Можно, но и так вроде неплохо. Сейчас протестирую удаление одним запросом, замерю время создания индексов, и будет понятно стоит ли дальше оптимизировать.
#91 by ptiz
Только что делать, если таблиц - десяток. Руками с ума сойдешь индексы удалять/пересоздавать :( А то мне предстоит скоро таблицы на сотни миллионов записей чистить.
#92 by VS-1976
Да скрипт готовишь используя SQL Server Management Studio. Можно ещё программно из 1С скрипт подготовить, используя ПолучитьСтруктуруХраненияБазыДанных
#93 by Genayo
По итогу - 30 млн записей удалились за 16 минут, 28 минут на пересоздание индексов. Дальше оптимизировать смысла не вижу.
#94 by Genayo
Ну да, для одного индекса получить скрипт на drop/create, дальше по аналогии для всех нужных индексов делаешь, и через ADODB запускаешь итоговый скрипт.
#95 by vis_tmp
А не попробовал?
#96 by VS-1976
Пятница только завтра... или ты решил со среды начать народ подогревать?
#97 by vis_tmp
Мне правда интересно. Я удалял много объектов этой одной командой.
#98 by Genayo
Порциями по 1 млн? Оно не подохнет по памяти?
Тэги: 1С 8
Ответить:
Комментарии доступны только авторизированным пользователям