Замена на копию таблицы с подмножеством данных вместо удаления из таблицы - лучший метод - PullRequest
0 голосов
/ 30 мая 2018

У нас есть таблица с 800M строками и 93 столбцами, которые требуют удаления исторических данных.Данные для удаления составляют> 95%.До сих пор попытки удаления в пакетах не увенчались успехом, по оценкам, по крайней мере одна неделя для завершения.Существующие индексы являются основной причиной медлительности.Удаление индексов и восстановление после удаления также оказалось слишком медленным в тестировании.

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

Проблема в том, что существует как минимум сто ключей, ограничений и индексов.

Мы рассматриваем создание сценария из Object Browser, переименование всех имен объектов с использованием поиска / замены, создание идентично структурированной таблицы, заполнение данными, переименование оригинала в качестве резервной копии, затем переименование новой таблицы и всех объектовк тем, которые содержатся в исходной таблице.

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

Какой самый надежный метод?Существует ли автоматизированный процесс для выполнения этой процедуры?Любые рекомендации приветствуются.

Ответы [ 2 ]

0 голосов
/ 04 июня 2018

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

select o.name as [Name],  o1.type as [Type], 'EXEC sp_rename N''' + o1.name + ''', '''  + o1.name + N'_OLD'''
from sys.objects o
inner join sys.objects o1 on o1.parent_object_id = o.object_id
where o.name = 'Product_history'
union
select o.name as [Name], 'I' as [Type], 'EXEC sp_rename N''PRODUCT_HISTORY.' + i.name + ''', '''  + i.name + N'_OLD'''
from sys.objects o
inner join sys.indexes i on i.object_id = o.object_id
where o.name = 'Product_history' and i.name is not null  AND i.is_primary_key = 0
order by [Type], [Name]


select o.name as [Name],  o1.type as [Type], 'EXEC sp_rename N''' + o1.name + ''', '''  + LEFT(o1.name,LEN(o1.name)-4) + N''''
from sys.objects o
inner join sys.objects o1 on o1.parent_object_id = o.object_id
where o.name = 'Product_history'
union
select o.name as [Name], 'I' as [Type], 'EXEC sp_rename N''PRODUCT_HISTORY.' + i.name + ''', '''  + LEFT(i.name,LEN(i.name)-4) + N''''
from sys.objects o
inner join sys.indexes i on i.object_id = o.object_id
where o.name = 'Product_history' and i.name is not null  AND i.is_primary_key = 0
order by [Type], [Name]
0 голосов
/ 30 мая 2018

Я бы сделал следующее во время простоя (то есть база данных никем не используется):

  1. Сценарий текущей таблицы, назовем ее [X] и переименуем в [Y].
  2. Запустите скрипт на шаге 1 и создайте новую таблицу, сохраняя [X]
  3. Вставьте в это [X] нужные вам записи из [Y], должно быть <5% от ваших 800 миллионов строк.(это все еще ~ 40M строк, потому что 800M X 5% = 40M).Конечно, чтобы ускорить этот шаг, вы можете рассмотреть вопрос о переключении модели восстановления на <code>SIMPLE и / или отключении триггеров / индексов ЧПУ и т. Д. После завершения работы вернитесь к исходным настройкам.
  4. Как только это будет сделано, настройте обычное задание, которое будет поддерживать новую таблицу [X], перемещая ненужные записи в [Y] каждый день.

Но окончательным решением будет обновление сервера SQL Server 2008 доSQL Server 2016+, в SQL Server 2016 с пакетом обновления 1 (SP1) даже стандартная редакция имеет возможность разделов, и этот метод разделов сделает вашу жизнь намного проще (хотя и другая тема)

...