2016-08-13 1 views
2

У меня есть таблица PROD_MAIN, которая имеет 750 миллионов записей в одной базе данных. Инфраструктура базы данных является очень простой и не содержит никаких RAC. Это всего лишь 1 база данных. Требование состоит в том, чтобы удалить записи, возраст которых превышает 1 год. Я написал код PL SQL с параллельной подсказкой и массивом. Это займет очень много времени. Пожалуйста, найдите код ниже.Удаление миллионов записей без параллельной подсказки и навального сбора

ALTER SESSION ENABLE PARALLEL DML; 

DECLARE 
TYPE TABLE_DELETE IS TABLE OF ROWID; 
T_DELETE TABLE_DELETE; 
CURSOR C_DELETE IS 
SELECT /*+ PARALLEL(10) */ ROWID FROM PROD_MAIN WHERE RECORD_DATE < (TRUNC(SYSDATE) - 366); 
L_DELETE_BUFFER PLS_INTEGER := 50000; 
BEGIN 
OPEN C_DELETE; 
LOOP 
FETCH C_DELETE BULK COLLECT 
INTO T_DELETE LIMIT L_DELETE_BUFFER; 
FORALL I IN 1..T_DELETE.COUNT 
DELETE /*+ PARALLEL(10) */ PROD_MAIN WHERE ROWID = T_DELETE(I); 
EXIT WHEN C_DELETE%NOTFOUND; 
COMMIT; 
END LOOP; 
CLOSE C_DELETE; 
COMMIT; 
END; 

ALTER SESSION DISABLE PARALLEL DML; 

Я также сделал NOLOGGING на столе. Я создал индексы и собирал стат, но производительность не улучшилась. Итак, есть ли другой способ, по которому я могу удалить миллионы записей в течение 3 - 5 часов?

+1

Какую часть строк вы удаляете? –

+0

@ Justin Cave: Я удаляю строки, которым больше 1 года. При проверке общее количество записей, которые необходимо удалить, составляет 400 миллионов из 750 миллионов. –

+0

ОК. И у вас есть пара часов простоя? Есть ли триггеры на столе? Является ли это родительской или дочерней таблицей в ограничении внешнего ключа? –

ответ

0

Я решил эту проблему, создав временную таблицу PROD_MAIN_TEMP, которая имеет точную структуру таблицы, такую ​​как PROD_MAIN. После создания я вставил данные, которые хочу сохранить. SELECT/* + PARALLEL (10) */* FROM PROD_MAIN WHERE RECORD_DATE < (TRUNC (SYSDATE) - 366); Выпало таблицу таблицы PROD_MAIN и переименовал временную таблицу PROD_MAIN_TEMP в PROD_MAIN. Весь процесс завершен через 3 часа.

+0

«Диего Саль Диаз» предложил это решение. –

1

Если таблица разделена по дате, Вы можете укоротить разделы с более чем за один год (усечение раздел занимает не раз Dont деградирует таблицу)

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

DELETE FROM your_table WHERE your_conditions LIMIT 10.000 (MySQL) 
DELETE FROM your_table WHERE your_conditions AND rownum <10000 (Oracle) 

Запомнить оптимизировать таблицу после окончания (или даже чередовать между удалений) из-за этого будет ухудшать индекс.

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

MyOriginalTable whit All Data 
Create en Empty Copy: MyTemporalTable (without indexes) 
Move valid data from MyOriginalTable to MyTemporalTable 
Truncate and Drop MyOriginalTable 
Create indexes in MyTemporalTable 
Rename MyTemporalTable to MyORiginalTable 
+0

Как разбить существующую таблицу PROD_MAIN на дату? Это новая концепция для меня. Будет ли это делать администратор базы данных или это сделает разработчики PL SQL? И я использую Oracle DB. Кроме того, мне нужно будет удалить по меньшей мере 400 миллионов записей за 2 - 3 часа. –

+0

Я думаю, что раздел должен быть bdone от dba, но создать раздел с таким количеством данных займет много времени. Если вы можете сделать второй вариант, возможно, это может быть лучше всего.Просто запомните, создайте таблицы, скопируйте индексы eithout и создайте их, когда заполняется таблица. – debus

+0

+1 для варианта 2, создайте новую таблицу, это самый эффективный способ. https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:2345591157689 – guigui42

1

Я думаю, что проблема в том, что эта таблица является главной таблицей для других таблиц.

Чтобы ускорить отключение этих внешних ключей в других таблицах. Затем удалите строки, затем включите индексы.

Но третье решение «Диего Саль Диаз», чтобы скопировать оставшуюся строку в таблицу темп и переименовать, тоже хорошо.