Пакетный SQL удаляет

Эта проблема очень хорошо решается пользователями Windows Server.

  1. . Перейдите по этому пути. C: \ Program Files \ MySQL \ MySQL Server 5.1 \ bin

  2. запустить этот инструмент «MySQLInstanceConfig.exe»

и снова сконфигурировать экземпляр, и проблема решена

11
задан Linger 4 September 2012 в 17:57
поделиться

8 ответов

Вы можете «откусите» удаление, что также означает, что вы не вызовете огромной нагрузки на базу данных. Если ваши резервные копии t-log выполняются каждые 10 минут, вы можете запустить это один или два раза с тем же интервалом. Вы можете запланировать его как задание агента SQL

, попробуйте что-то вроде этого:

DECLARE @count int
SET @count = 10000

    DELETE  FROM table1 
    WHERE table1id IN (
        SELECT TOP (@count) tableid
        FROM table1
        WHERE x='y'
    )
7
ответ дан 3 December 2019 в 04:53
поделиться

Чем отличаются строки, которые вы хотите удалить, от тех, которые вы хотите сохранить? Будет ли это работать для вас:

while exists (select 1 from your_table where <your_condition>)
delete top(10000) from your_table
where <your_condition>
8
ответ дан 3 December 2019 в 04:53
поделиться

Похоже, что это разовая операция (я надеюсь на вас), и вам не нужно возвращаться в состояние, которое находится на полпути к этому пакетному удалению - если это так, почему бы и нет вы просто переключаетесь в режим SIMPLE транзакции перед запуском, а затем обратно в FULL, когда закончите?

Таким образом, журнал транзакций не будет так сильно увеличиваться. Это может быть не идеально в большинстве ситуаций, но я не вижу здесь ничего плохого (при условии, что, как указано выше, вам не нужно возвращаться в состояние, которое находится между удалениями).

вы можете сделать это в своем скрипте с помощью smt как:

ALTER DATABASE myDB SET RECOVERY FULL/SIMPLE

В качестве альтернативы вы можете настроить задание для сжатия журнала транзакций через каждый заданный интервал времени - пока выполняется удаление. Это довольно плохо, но я думаю, что это поможет.

3
ответ дан 3 December 2019 в 04:53
поделиться

Что ж, если бы вы использовали секционирование SQL Server, скажем, на основе столбца даты, вы, возможно, отключили бы разделы, которые больше не нужны. Возможно, стоит рассмотреть вопрос о будущей реализации.

Я думаю, что лучшим вариантом может быть, как вы говорите, удаление данных небольшими партиями, а не одним обращением, чтобы избежать любых потенциальных проблем с блокировкой.

Вы могли бы также рассмотрите следующий метод:

2
ответ дан 3 December 2019 в 04:53
поделиться

Я бы сделал что-то похожее на предложения временной таблицы, но я бы выбрал новый постоянную таблицу строки, которые вы хотите сохранить, удалите исходную таблицу и переименуйте новую. Это должно иметь относительно низкое влияние на транзакцию. Очевидно, не забудьте воссоздать все индексы, которые требуются для новой таблицы после того, как вы ее переименовали.

Только мои два p'enneth.

2
ответ дан 3 December 2019 в 04:53
поделиться

В дополнение к помещению этого в пакет с оператором для усечения журнала вы также могут захотеть попробовать эти уловки:

  • Добавьте критерии, которые соответствуют первому столбцу в вашем кластеризованном индексе в дополнение к вашим другим критериям.
  • Удалите все индексы из таблицы и затем верните их после удаления, если это возможно и не будет мешать чему-либо еще, происходящему в БД, но СОХРАНИТЕ кластерный индекс

. Например, для первого пункта выше, если ваш ПК кластеризован, найдите диапазон, который приблизительно соответствует количеству строк, которые вы хотите чтобы удалить каждый пакет и использовать это:

DECLARE @max_id INT, @start_id INT, @end_id INT, @interval INT
SELECT @start_id = MIN(id), @max_id = MAX(id) FROM My_Table
SET @interval = 100000  -- You need to determine the right number here
SET @end_id = @start_id + @interval

WHILE (@start_id <= @max_id)
BEGIN
     DELETE FROM My_Table WHERE id BETWEEN @start_id AND @end_id AND <your criteria>

     SET @start_id = @end_id + 1
     SET @end_id = @end_id + @interval
END
2
ответ дан 3 December 2019 в 04:53
поделиться

Я согласен с людьми, которые хотят, чтобы вы перебирали меньший набор записей, это будет быстрее, чем пытаться выполнить всю операцию за один шаг. Вы можете испытать количество записей, которые следует включить в цикл. Около 2000 за раз кажутся золотыми пятнами для большинства таблиц. Я делаю большие дельты, хотя некоторым нужны меньшие суммы, например 500. Зависит от количества иностранных ключей, размера записи, триггеров и т. Д., Так что это действительно займет некоторые экспериментируют, чтобы найти то, что вам нужно. Это также зависит от того, насколько интенсивно использование стола. Таблица с интенсивным доступом потребует, чтобы каждая итерация цикла выполнялась за меньшее время. Если вы можете работать в нерабочее время или, лучше всего, в однопользовательском режиме, вы можете удалить больше записей за один цикл.

Если вы не думаете, что сделаете это за одну ночь в нерабочее время, Возможно, лучше всего разработать цикл со счетчиком и делать только определенное количество итераций каждую ночь, пока это не будет выполнено.

Кроме того, если вы используете неявную транзакцию, а не явную, вы можете завершить запрос цикла на в любой момент уже удаленные записи останутся удаленными, за исключением тех, которые находятся в текущем раунде цикла. Гораздо быстрее, чем пытаться откатить полмиллиона записей, потому что вы остановили систему.

Обычно рекомендуется создавать резервную копию базы данных непосредственно перед выполнением операции такого рода.

вы можете завершить запрос цикла в любое время, и уже удаленные записи останутся удаленными, за исключением тех, которые находятся в текущем цикле цикла. Гораздо быстрее, чем пытаться откатить полмиллиона записей, потому что вы остановили систему.

Обычно рекомендуется создавать резервную копию базы данных непосредственно перед выполнением операции такого рода.

вы можете завершить запрос цикла в любое время, и уже удаленные записи останутся удаленными, за исключением тех, которые находятся в текущем цикле цикла. Гораздо быстрее, чем пытаться откатить полмиллиона записей, потому что вы остановили систему.

Обычно рекомендуется создавать резервную копию базы данных непосредственно перед выполнением операции такого рода.

0
ответ дан 3 December 2019 в 04:53
поделиться

Короткий ответ: вы не можете удалить 2 миллиарда строк без какого-либо серьезного простоя базы данных.

Лучшим вариантом может быть копирование данных во временную таблицу и усечение исходную таблицу, но это заполнит вашу базу данных tempDB и будет использовать не меньше протоколирования, чем удаление данных.

Вам нужно будет удалить столько строк, сколько сможете, пока журнал транзакций не заполнится, а затем каждый раз усекать его. Ответ, предоставленный Станиславом Князевым, можно было изменить для этого, увеличив размер пакета и добавив вызов для усечения файла журнала.

-1
ответ дан 3 December 2019 в 04:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: