2016-06-10 3 views
0

Удалить SQL-скрипты занимают очень много времени и даже вешают навсегда в Oracle 12c. У нас есть сотни скриптов для удаления, как показано ниже, и даже пытались запустить его с помощью параллельной работы/* + PARALLEL (a, 4) * /, но не повезло в улучшении производительности.Удалить SQL - Принимать навсегда

  1. Есть ли способ настроить скрипты удаления.
  2. Можем ли мы использовать PL/SQL для цикла, чтобы улучшить производительность?
  3. Если да, то, пожалуйста, поделитесь своими мыслями и советами.

Некоторые примеры сценарии SQL:

DELETE 
FROM 
E_PROJ_DETAIL 
WHERE 
CATEGORY_ID in (SELECT PRIMARY_KEY FROM Y_OBJ_CATEGORY WHERE TREE_POSITION='VEN$_MADD'); 

COMMIT; 

delete 
from 
e_proj_group_access 
where enterprise_object_id in (select primary_key from t_project where application_id in (select application_id from y_object_definition where unique_code ='VEN$_MADD')); 

commit; 
+2

Сколько строк в y_obj_category, как человек в e_proj_detail? имеет ли category_id индекс? и т. д. Что вы должны сделать, так это посмотреть на план выполнения. – Hogan

+2

Трудно ответить без подробных подробностей (которые вы, вероятно, не можете предоставить). Мои непосредственные мысли: 1) есть проблемы с индексами, 2) кто-то реализовал триггер где-то, что замедляет работу. – Paulb

+3

В связи с догадками @ Paulb будет вопрос о том, есть ли необъявленные внешние ключи (это тип проблемы с индексом, но тот, который я вызывал отдельно). –

ответ

0

Я не знаю, о каких-либо возможностях для «настроить» ВЕИТ, может быть, за исключением каких-либо бесполезные падают (= неиспользуемые) индексы и ограничение заранее и воссоздавать их после этого.

В этих случаях (удаление большого количества строк) Я использовал FOR петли с совершает внутри, что-то вроде этого:

I := 0; 
FOR c IN (SELECT id FROM table WHERE [conditions to delete]) 
LOOP 
    DELETE FROM table WHERE t.id = c.id; /* id = primary key */ 
    IF (I > 1000) THEN 
     COMMIT; 
     I := 0; 
    END IF; 
    I := I + 1; 
END LOOP; 

Но здесь вы можете время от времени впадать в ORA-01555: snapshot too old, потому что вы будете удалять строки из тех же таблиц из который вы открыли курсором в цикле FOR.

В других ситуациях вы можете сделать CREATE TABLE newtable AS SELECT * FROM oldtable WHERE [conditions for rows I want to keep], а затем сделать TRUNCATE oldtable и INSERT /*+ APPEND */ INTO oldtable SELECT * from newtable;, чтобы написать правильные данные.

Это действительно зависит от ситуации, в которой вы находитесь (как прокомментировали другие - сколько строк у вас есть в таблице, сколько строк вы хотите удалить и т. Д.).

НТН :-)

0

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

CREATE TABLE E_PROJ_DETAIL_NEW AS 
SELECT * FROM 
E_PROJ_DETAIL 
WHERE 
CATEGORY_ID NOT IN (SELECT PRIMARY_KEY FROM Y_OBJ_CATEGORY WHERE TREE_POSITION='VEN$_MADD'); 

Затем удалить старой таблицы и переименовать новую.

Возможно, вам понадобится заново создать индексы/fk, если у вас их есть.