как создать план выполнения для оракула цикла - PullRequest
1 голос
/ 22 декабря 2010

Как я могу сгенерировать план выполнения для запроса цикла oracle, как показано ниже:

BEGIN 
  FOR L IN (SELECT FIRST_NAME, LAST_NAME, SOME_ID FROM TABLE1)
  LOOP
      INSERT INTO TABLE2 (FIRSTNAME, LASTNAME)
      (SELECT FNAME, LASTNAME FROM TABLE2 WHERE SOME_ID = L.SOME_ID)

  V_CNT := V_CNT + 1;

  IF (MOD(V_CNT, 1000)=0) THEN
    COMMIT;
  END IF;

END LOOP;

Как я могу сгенерировать план выполнения для блока, как указано выше?

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

Ответы [ 3 ]

3 голосов
/ 22 декабря 2010

Ваш блок PL / SQL может быть переписан на SQL:

INSERT INTO table2 (firstname, lastname)
   SELECT fname, lastname
     FROM table2
    WHERE some_id IN (SELECT some_id FROM table1);

Затем вы можете «объяснить план» вышеупомянутой ВСТАВКИ.

Если вам нужно выполнить пакетную фиксацию, тогда использование BULK COLLECT ... LIMIT и FORALL более эффективно, чем курсор для цикла, особенно если вы обрабатываете миллионы строк. Полезные ссылки:

1 голос
/ 22 декабря 2010

Если вас интересует производительность вашего процедурного кода PL / SQL, вы можете изучить вопрос о профилировании PL / SQL.

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

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

Хорошее первое введение здесь: Профиль СУБД Oracle

1 голос
/ 22 декабря 2010

Невозможно сгенерировать планы выполнения для блоков PL/SQL, только для запросов.

План выполнения показывает, как декларативные команды (SQL) выполняются под капотом, т.е. е. какие процедуры используются. Он преобразует декларативные конструкции (операции над множествами) в процедуры (вложенные циклы, хэш-соединения, сортировки и т. Д.).

PL/SQL, будучи, как следует из названия, процедурным языком, определяет сам план выполнения - вложенные циклы в вашем случае.

Если вы хотите увидеть план выполнения внутреннего запроса, скопируйте его и введите EXPLAIN PLAN FOR …

Обратите внимание, что это может быть более эффективно переписано как:

BEGIN 
        FOR L IN
        (
        SELECT  MIN(some_id) AS minid, MAX(some_id) AS maxid
        FROM    (
                SELECT  some_id, rownum AS rn
                FROM    (
                        SELECT  some_id
                        FROM    table1
                        ORDER BY
                                some_id
                        )
                )
        GROUP BY
                TRUNC(rn / 1000)
        )
        LOOP
                INSERT
                INTO    TABLE2 (FIRSTNAME, LASTNAME)
                SELECT  FNAME, LASTNAME
                FROM    table1
                JOIN    table2
                ON      table2.some_id = table1.some_id
                WHERE   table1.some_id BETWEEN l.minid AND l.maxid
                V_CNT := V_CNT + 1;
                IF (MOD(V_CNT, 1000)=0) THEN
                        COMMIT;
                END IF;
        END LOOP;
END;
...