본문 바로가기
Database

[ Oracle ] PL/SQL과 내장 함수 및 SQL의 비교

by Lcoding 2025. 1. 3.
반응형

안녕하세요.

 

오늘은 PL/SQL과 내장 함수 및 SQL 속도에 대하여 알아보겠습니다.

 

PL/SQL이 네이티브 코드로 완전히 컴파일된 내장 함수에 비해 상대적으로 느리게 동작하는데요.

 

PL/SQL은 Java와 비슷하게 인터프리터(interpreter) 언어로 동작하는 측면이 있습니다.

PL/SQL 코드는 데이터베이스 내에서 실행되며, SQL 엔진과 PL/SQL 엔진 간의 상호작용이 필요합니다.

이 때문에 PL/SQL은 데이터베이스의 native 코드로 완전히 컴파일된 함수나 프로시저에 비해 상대적으로 느릴 수 있습니다.

 

[ 1 ]

물론 Java와 비슷한거지 Java 인터프리터 언어와 완전히 동일하다고 할 수는 없습니다.

 

  1. PL/SQL 컴파일 방식
    PL/SQL 코드는 데이터베이스에 저장되면서 바이트코드로 컴파일됩니다. 실행 시 PL/SQL 엔진이 바이트코드를 해석하거나 최적화된 네이티브 코드로 변환하여 실행합니다.
  2. 최적화된 엔진
    Oracle Database는 PL/SQL 엔진과 SQL 엔진 간의 통합 작업을 최적화하여 성능 저하를 줄입니다. 특히, 네트워크 트래픽이 필요 없기 때문에 클라이언트-서버 모델에서 발생할 수 있는 오버헤드가 없습니다.
  3. 네이티브 컴파일
    Oracle은 PL/SQL 코드를 네이티브 코드(C 코드)로 컴파일할 수 있는 기능을 제공합니다. 이렇게 하면 성능이 크게 개선됩니다. (다만, 이 방식은 설정 및 운영에 추가적인 복잡성이 있습니다.)

정리

PL/SQL은 기본적으로 인터프리터 방식으로 실행되므로 네이티브 코드로 완전히 컴파일된 함수보다는 느릴 수 있습니다. 그러나 데이터베이스 내에서 실행되므로 네트워크 오버헤드가 없고, 최적화된 엔진 덕분에 많은 경우 Java 같은 일반적인 인터프리터 언어보다는 효율적으로 작동합니다.

 

 

 

** 심화 단계  **

[2]

PL/SQL이 네이티브 코드로 완전히 컴파일된 내장 함수에 비해 상대적으로 느리게 동작하는것에 대하여 좀더 깊게 알아보겠습니다.

 

 

PL/SQL은 네이티브 코드로 작성된 내장 함수보다 느릴 수 있는데, 이는 컨텍스트 스위칭, 인터프리터 방식 실행, 재귀 호출의 부하 등 여러 이유에서 기인합니다. 재귀 호출이 성능에 미치는 영향을 포함해 살펴보겠습니다.

 

1. 컨텍스트 스위칭(Context Switching)

PL/SQL과 SQL 엔진 간 상호작용에서 발생하는 컨텍스트 스위칭은 PL/SQL의 주요 성능 저하 요인 중 하나입니다.

작동 방식

  • PL/SQL 블록에서 SQL 문이 실행되면, PL/SQL 엔진이 SQL 엔진으로 제어를 넘겨야 합니다.
  • SQL 엔진이 작업을 수행한 뒤 결과를 PL/SQL로 반환하면, 다시 PL/SQL 컨텍스트로 전환해야 합니다.

컨텍스트 스위칭 비용

  • CPU 오버헤드: 각 전환 시 상태 저장 및 복구.
  • 데이터 이동 비용: SQL과 PL/SQL 간 데이터 교환.

예시 -
다음 PL/SQL 코드는 SQL 문이 반복적으로 호출되며 매번 컨텍스트 스위칭이 발생합니다.

DECLARE
  total_sales NUMBER;
BEGIN
  FOR i IN 1..1000 LOOP
    SELECT SUM(sales) INTO total_sales FROM sales_table WHERE id = i;
  END LOOP;
END;

 

이 경우 1,000번의 컨텍스트 전환이 발생하므로 실행 속도가 크게 저하될 수 있습니다.

 

 

개선 방안 -

  • 가능하다면 단일 SQL 문으로 작업을 병합.
SELECT id, SUM(sales) 
INTO   total_sales 
FROM   sales_table 
GROUP  BY id;

 

 

2. 인터프리터 방식 실행

PL/SQL은 기본적으로 바이트코드로 변환된 후 실행됩니다.

 

이 방식은 네이티브 코드와 비교해 다음과 같은 성능 저하를 유발합니다.

  • 명령 해석 시간: 바이트코드가 실행될 때마다 PL/SQL 엔진이 이를 해석해야 함.
  • 추가적인 런타임 오버헤드: 실행 중 추가적인 관리 작업이 필요.

네이티브 코드는 CPU에서 바로 실행되는 반면, PL/SQL은 이 중간 과정이 필요하기 때문에 느릴 수 있습니다.

 

 

개선 방안 -

  • PL/SQL 코드를 네이티브 코드로 컴파일하는 기능을 활용(Oracle Database의 NATIVE 옵션).

 

 

3. 재귀 호출(Recursive Call)의 부하

재귀 호출이란?

재귀 호출은 함수가 자신을 호출하는 방식으로, 문제를 반복적으로 작은 부분으로 나누는 데 유용합니다.

하지만 반복적으로 호출되는 동안 스택 메모리 사용함수 호출 오버헤드가 누적되어 성능에 부정적인 영향을 줄 수 있습니다.

PL/SQL에서의 예시

재귀 호출을 사용한 팩토리얼 계산 방식 - 

CREATE OR REPLACE FUNCTION factorial(n NUMBER) RETURN NUMBER IS
BEGIN
  IF n = 0 THEN
    RETURN 1;
  ELSE
    RETURN n * factorial(n - 1);
  END IF;
END;
/

 

위 함수는 호출될 때마다 함수 스택이 쌓입니다. factorial(5)를 계산하면 함수는 총 5번 호출되며,

각 호출 시 스택 메모리와 함수 호출 오버헤드가 발생합니다.

재귀 호출의 성능 부하

  • 스택 메모리 소모: 함수 호출 시마다 스택에 상태를 저장. 깊은 재귀 호출은 메모리 부족을 유발할 수 있음.
  • 함수 호출 오버헤드: 호출 시마다 변수 초기화, 상태 저장 및 복구 등 추가 작업 발생.

 

개선 방안 -

재귀 호출은 반복문으로 대체해 성능을 최적화할 수 있습니다.

CREATE OR REPLACE FUNCTION factorial_iterative(n NUMBER) RETURN NUMBER IS
  result NUMBER := 1;
BEGIN
  FOR i IN 1..n LOOP
    result := result * i;
  END LOOP;
  RETURN result;
END;
/

 

위 반복문 기반 팩토리얼 계산은 재귀 호출에 비해 메모리 사용량과 함수 호출 오버헤드가 적습니다.

 

4. 내장 함수와 PL/SQL의 비교

Oracle 내장 함수는 데이터베이스 엔진에 최적화된 네이티브 코드로 작성되며 다음과 같은 이점이 있습니다:

  1. 컨텍스트 스위칭 없음: 내장 함수는 SQL 엔진 내에서 실행되므로 PL/SQL과 SQL 간 전환이 필요 없음.
  2. 네이티브 코드 실행: 명령어가 CPU에서 직접 실행됨.
  3. 고도로 최적화된 알고리즘: Oracle 개발자가 데이터 구조와 알고리즘을 최적화.

예시 비교 -
PL/SQL로 작성한 문자열 연결과 Oracle 내장 함수 사용 비교.

-- PL/SQL 방식 (느림)
DECLARE
  result VARCHAR2(4000) := '';
BEGIN
  FOR i IN 1..1000 LOOP
    result := result || 'Hello';
  END LOOP;
END;

 

-- Oracle 내장 함수 방식 (빠름)
SELECT RPAD('Hello', 5000, 'Hello') INTO result FROM dual;

 

내장 함수는 PL/SQL보다 훨씬 빠르게 실행됩니다.

요약

PL/SQL이 내장 함수보다 느린 이유는 다음과 같습니다.

  1. 컨텍스트 스위칭: PL/SQL과 SQL 엔진 간의 전환 비용.
  2. 인터프리터 방식 실행: 네이티브 코드에 비해 실행 시간이 더 필요.
  3. 재귀 호출의 부하: 스택 메모리 사용과 함수 호출 오버헤드.
  4. 런타임 환경: 네이티브 함수는 PL/SQL보다 더 최적화된 데이터 처리 환경을 가짐.

개선 방안 -

  • 단일 SQL 문으로 작업 병합.
  • 반복문 사용으로 재귀 호출 대체.
  • PL/SQL 코드를 네이티브 코드로 컴파일.
  • PL/SQL의 집합 연산(FORALL, BULK COLLECT) 활용.

이런 방법을 통해 PL/SQL의 성능 저하 문제를 완화할 수 있습니다.

 

 

감사합니다.

 

 

 

 

 

 

반응형

# 로딩 화면 동작 코드(Code) 설정하기
loading