У меня есть большая таблица данных. В этой таблице 10 миллионов записей.
Как лучше всего выполнить этот запрос
Delete LargeTable where readTime < dateadd(MONTH,-7,GETDATE())
sql-server
sql-server-2008
sql-optimization
user3107343
источник
источник
Ответы:
Если вы удаляете все строки в этой таблице, самым простым вариантом является усечение таблицы, что-то вроде
Таблица Truncate просто очистит таблицу, вы не можете использовать предложение WHERE для ограничения удаляемых строк, и никакие триггеры не будут срабатывать.
С другой стороны, если вы удаляете более 80-90 процентов данных, скажем, если у вас всего 11 миллионов строк и вы хотите удалить 10 миллионов, другим способом было бы Вставить эти 1 миллион строк (записи, которые вы хотите сохранить ) в другой промежуточный стол. Обрежьте эту большую таблицу и вставьте обратно эти 1 миллион строк.
Или, если разрешения / представления или другие объекты, которые имеют эту большую таблицу в качестве базовой таблицы, не пострадают при удалении этой таблицы, вы можете получить это относительно небольшое количество строк в другой таблице, отбросьте эту таблицу и создайте другую таблицу с той же схемой и импортируйте их. строк обратно в эту бывшую большую таблицу.
Последний вариант, о котором я могу подумать, - это изменить вашу базу данных,
Recovery Mode to SIMPLE
а затем удалять строки меньшими партиями, используя цикл while примерно так ...и не забудьте снова изменить режим восстановления на полный, и я думаю, вам нужно сделать резервную копию, чтобы сделать ее полностью эффективной (режимы изменения или восстановления).
источник
optimal solution for unknown case
это мечта, не так ли? К сожалению, вы не можете вылечить каждую болезнь одной таблеткой; Я предложил несколько возможных решений для разных сценариев. К сожалению, здесь нет серебряной пули.@ m-ali ответ правильный, но имейте в виду, что журналы могут сильно вырасти, если вы не фиксируете транзакцию после каждого фрагмента и не выполняете контрольную точку. Вот как я бы сделал это и взял эту статью http://sqlperformance.com/2013/03/io-subsystem/chunk-deletes в качестве справочной с тестами производительности и графиками:
источник
COMMIT TRANSACTION
иCHECKPOINT
журналы по - прежнему растет. Спасибо, что разъяснили это.@Deleted_Rows
с 10000, или у вас может получиться бесконечный цикл из-за того, что он бесконечно удаляет небольшие наборы данных. ИтакWHILE (@Deleted_Rows = 10000)
- как только не будет полной «страницы» данных для удаления, она остановится. В вашей реализацииWHILE (@Deleted_Rows > 0)
цикл while будет выполняться снова, даже если он удалил только одну строку, и следующее выполнение может также найти строку или две для удаления, что приведет к бесконечному циклу.WHILE
самого цикла:dateadd(MONTH,-7,GETDATE())
.WHILE
цикла.Вы также можете использовать GO +, сколько раз вы хотите выполнить один и тот же запрос.
источник
GO xx
должен работать этот синтаксис ? Я получаю сообщение об ошибке «Не удалось найти хранимую процедуру» . Однако безGO
команды он работает нормально.@Francisco Goldenstein, небольшая поправка. COMMIT необходимо использовать после установки переменной, иначе WHILE будет выполнен только один раз:
источник
Эта вариация M.Ali мне подходит. Некоторые удаляются, журнал очищается и повторяется. Я смотрю, как журнал растет, опускается и начинается сначала.
источник
# of rows
удаление за раз, а такжеWHERE
предложение. Работает как шарм!Если вы хотите (и можете) реализовать секционирование, это эффективный метод для удаления больших объемов данных с небольшими затратами времени выполнения. Однако это не рентабельно для разового упражнения.
источник
Я смог удалить 19 миллионов строк из моей таблицы, состоящей из 21 миллиона строк, за считанные минуты . Вот мой подход.
Если у вас есть автоматически увеличивающийся первичный ключ в этой таблице, вы можете использовать этот первичный ключ.
Получить минимальное значение первичного ключа большой таблицы, где readTime <dateadd (MONTH, -7, GETDATE ()). (Добавьте индекс в readTime, если он еще не присутствует, этот индекс все равно будет удален вместе с таблицей на шаге 3.). Сохраним его в переменной min_primary.
Вставьте все строки с первичным ключом> min_primary в промежуточную таблицу (таблица памяти, если количество строк невелико).
Бросьте большой стол.
Восстановите таблицу. Скопируйте все строки из промежуточной таблицы в основную.
Отбросьте промежуточный стол.
источник
Вы можете удалять небольшие партии, используя цикл while, примерно так:
источник
Другое использование:
По желанию;
Если журнал транзакций включен, отключите журналы транзакций.
источник
Более короткий синтаксис
источник
Если вы используете SQL Server 2016 или выше, и если в вашей таблице есть разделы, созданные на основе столбца, который вы пытаетесь удалить (например, столбец Timestamp), вы можете использовать эту новую команду для удаления данных по разделам.
ОБРЕЗАТЬ ТАБЛИЦУ С (РАЗДЕЛЫ ({|} [, ... n]))
Это приведет к удалению данных только в выбранном разделе (ах) и должно быть наиболее эффективным способом удаления данных из части таблицы, поскольку при этом не будут создаваться журналы транзакций и будет выполняться так же быстро, как и при обычном усечении, но без удаления всех данных. из таблицы.
Недостатком является то, что если ваша таблица не настроена с разделением, вам нужно пойти по старой школе и удалить данные с помощью обычного подхода, а затем воссоздать таблицу с разделами, чтобы вы могли сделать это в будущем, что я и сделал. Я добавил создание и удаление разделов в саму процедуру вставки. У меня была таблица с 500 миллионами строк, так что это был единственный способ сократить время удаления.
Для получения дополнительных сведений см. Ссылки ниже: https://docs.microsoft.com/en-us/sql/t-sql/statements/truncate-table-transact-sql?view=sql-server-2017
Таблица усечения SQL Server 2016 с разделами
Ниже показано, что я сделал сначала, чтобы удалить данные, прежде чем смог воссоздать таблицу с разделами с необходимыми данными в ней. Этот запрос будет выполняться в течение нескольких дней в течение указанного временного окна, пока данные не будут удалены.
источник
Если я говорю без цикла, я могу использовать
GOTO
оператор для удаления большого количества записей с помощью sql-сервера. экс.таким образом вы можете удалить большой объем данных с меньшим размером удаления.
дайте мне знать, если потребуется дополнительная информация.
источник