2017-12-15 1 views
2

익명 블록 안에 많은 코드가 있는데 PL/SQL 최적화 프로그램이이 코드를 최적화하지 않을까 걱정됩니다. 익명 블록에서 내 코드를 패키지로 이동시켜 옵티마이 저가 모든 작업을 수행하도록해야합니까?Oracle PL/SQL 최적화 프로그램은 익명 블록을 최적화하거나 프로그램 단위를 저장합니까?

+2

s.o에서 활약하는 것을 좋아합니다. 귀하의 대답은 아주 자세하지만 질문은 지나치게 광범위합니다. :). BTW, Oracle에 대한 PLSQL "전도자"로서의 귀하의 기여에 진심으로 감사드립니다. –

답변

5

제목 질문에 대한 답변은 다음과 같습니다. 예. 최적화 프로그램은 익명 블록 및 저장된 프로그램 단위를 최적화합니다. 이 진술을 확인하려면 답안의 끝에서 스크립트를 참조하십시오.

두 번째 질문에 대한 대답은 다음과 같습니다. 예, 코드를 익명 블록에서 패키지로 옮겨야합니다.

두 번째 예는 성능과 아무 관련이 없습니다. 많은 양의 코드를 관리해야하는 어려움과 관련이 있습니다. 패키지보다는 스크립트 파일에서 코드를 관리하는 것이 훨씬 더 어렵습니다. 또한 명명 된 프로그램 단위에 코드를 저장하면 종속성 관리, 프로그램 무효화 및 자동 재 컴파일, PL/Scope를 사용한 코드 분석 등 코드와 관련하여 Oracle Database에서 제공하는 모든 이점을 활용할 수 있습니다.

이제 옵티마이 저가 익명 블록에 대한 마법을 수행한다는 것을 알기 위해 12.2에서 실행되는 다음 명령문 시퀀스를 고려하십시오.

우선 타이밍을 설정하고 최적화 레벨을 가능한 최대로 설정합니다 (레벨 2는 기본값이며 대량 최적화 수행, 레벨 3은 서브 프로그램 인라이닝을 추가하며 PL/SQL 개발 팀에서 권장 함) .

SET TIMING ON 

ALTER SESSION SET plsql_optimize_level = 3 
/

이 첫 번째 블록에서는 커서 FOR 루프를 사용하여 전체 행을 반복합니다. 옵티마 이저 이 자동으로이를 BULK COLLECT 명령문과 동등하게 컴파일해야합니다 (한 번에 기본값 100 행 가져 오기).

SQL> DECLARE 
    2  n INT; 
    3 BEGIN 
    4  FOR rec IN (SELECT * FROM all_objects) 
    5  LOOP 
    6  n := n + 1; 
    7  END LOOP; 
    8 
    9  DBMS_OUTPUT.put_line (n); 
10 END; 
11/

Elapsed: 00:00:01.943 

2 초 미만입니다. 최적화 되었습니까? 비교를 통해 확인합시다.

이 두 번째 블록에서는 더 이상 커서 FOR 루프를 사용하지 않습니다. 대신 커서를 명시 적으로 선언 한 다음 한 번에 하나씩 행을 반복합니다. 이 방법을 사용하면 옵티마이 저가 더 이상이 코드를 대량 가져 오기로 안전하게 변환 할 수 없으므로 속도가 훨씬 느려집니다.

SQL> DECLARE 
    2  n INT; 
    3 
    4  CURSOR obj_cur 
    5  IS 
    6  SELECT * FROM all_objects; 
    7 
    8  r obj_cur%ROWTYPE; 
    9 BEGIN 
10  OPEN obj_cur; 
11 
12  LOOP 
13  FETCH obj_cur INTO r; 
14  EXIT WHEN obj_cur%NOTFOUND; 
15  n := n + 1; 
16  END LOOP; 
17  
18  CLOSE obj_cur; 
19 
20  DBMS_OUTPUT.put_line (n); 
21 END; 
22/

Elapsed: 00:00:04.648 

첫 번째 블록보다 느리다. 결론 : 익명 블록이 최적화되었습니다. 첫 번째 블록의 성능을 저장 프로 시저의 성능과 비교해 보겠습니다.

SQL> CREATE OR REPLACE PROCEDURE count_objects 
    2 IS 
    3  n INT; 
    4 BEGIN 
    5  FOR rec IN (SELECT * FROM all_objects) 
    6  LOOP 
    7  n := n + 1; 
    8  END LOOP; 
    9 
10  DBMS_OUTPUT.put_line (n); 
11 END; 
12/

SQL> BEGIN 
    2  count_objects; 
    3 END; 
    4/

Elapsed: 00:00:01.875 

대략 동일합니다. 거기에 익명 블록이 저장된 프로그램 단위처럼 최적화되어 있습니다. 즐겨!

관련 문제