Вопросы, связанные с эффективным DML в процедуре / функциях - PullRequest
1 голос
/ 01 декабря 2011

У меня есть 2 вопроса относительно производительности сценария PL / SQL при выполнении DML. Конечно, EXECUTE IMMEDIATE - самый медленный, поэтому у нас есть forall, bulk вставка и т. Д. Мои вопросы

  1. Я должен манипулировать данными в 3 разных таблицах. Table1 (вставить данные), Table2 (обновить данные) и Table3 удалить данные. Все это будет сделано на основе значений, выбранных с помощью курсора. вопрос в том, что будет более эффективным здесь?
    • Поместить каждое из этих утверждений в отдельный блок Forall? т.е.
fetch cursor
loop
   forall loop for table 1
   forall loop for table 2
   forall loop for table 3
end loop

OR

  • глобальный цикл и выполнение этих инструкций в этом цикле, т.е.
fetch cursor loop
    for i IN array.count 
    loop
       3 statements for DML
    end loop end loop

Теперь мой второй вопрос

  1. каков эффективный способ удаления записей в цикле? Я выбрал значения записей, которые будут удалены через курсор. Каков же эффективный способ их удаления?

P.S: Выполните мое форматирование

1 Ответ

4 голосов
/ 01 декабря 2011

Самый эффективный подход - написать три оператора SQL, предполагая, что данные, извлекаемые из курсора, стабильны в течение периода времени, в течение которого выполняется процедура

INSERT INTO table1( list_of_columns )
  <<your SELECT statement>>

UPDATE table2
   SET (<<list of columns>>) = (<<your SELECT statement joined to table2>>)
 WHERE EXISTS( <<your SELECT statement joined to table2>> );

DELETE FROM table3
 WHERE EXISTS( <<your SELECT statement joined to table3>> );

Если оператор SELECT потенциально будет возвращать разные результаты в каждом из трех операторов DML, то имеет смысл принять снижение производительности при использовании курсора, массового сбора данных в коллекции PL / SQL и циклического выполнения по коллекции для обеспечения последовательных результатов. Если это то, что вы делаете, было бы более эффективно иметь три оператора FORALL, поскольку это потребует меньшего количества изменений контекста между механизмами SQL и PL / SQL.

Каков эффективный способ удаления записей в цикле? Я выбрал значения записей, которые будут удалены через курсор. Каков же эффективный способ их удаления?

Я не уверен, что понимаю вопрос. Не могли бы вы просто сделать цикл FORALL, как если бы вы сделали INSERT или UPDATE

FORALL i IN l_array.first .. l_array.last
  DELETE FROM some_table
   WHERE some_key = l_array(i);

Или вы задаете другой вопрос?

...