DAP 자격증

[DAP자격증] 과목5 - SQL 통계정보 보는법 (Parse, Execute, Fetch)

IronAreum 2025. 3. 27. 22:34
728x90

SQL 성능 개선을 위해 SQL 통계 정보를 확인할 때, CALL의 Parse, Execute, Fetch 단계와 COUNT, ROWS 값이 어떤 의미를 가지는지 정확히 이해하는 것이 중요해.


1. SQL Call의 3가지 단계: Parse, Execute, Fetch

데이터베이스에서 SQL을 실행하면 3가지 주요 단계를 거쳐.

1) Parse (파싱 단계)

  • SQL 문을 데이터베이스가 해석하고 실행 계획을 생성하는 과정
  • 주요 작업:
    • SQL 문법 체크
    • 객체(테이블, 인덱스 등) 유효성 검증
    • 실행 계획(Execution Plan) 생성 또는 재사용 (Hard Parse vs. Soft Parse)

🔹 Hard Parse vs. Soft Parse

  • Hard Parse: 처음 실행되는 SQL이거나 실행 계획을 새로 만들어야 하는 경우 (비효율적)
  • Soft Parse: 기존 실행 계획을 재사용하는 경우 (효율적)

2) Execute (실행 단계)

  • SQL이 실행되는 단계로, DML(SELECT 제외)에서는 데이터 변경 작업이 수행됨.
  • 주요 작업:
    • WHERE 절에 맞는 데이터를 찾음
    • 필요한 경우 데이터 변경 수행 (INSERT, UPDATE, DELETE)

3) Fetch (데이터 조회 단계)

  • SELECT문의 경우, 찾은 데이터를 클라이언트로 전송하는 단계
  • FETCH 횟수가 많으면 네트워크 비용이 증가하여 성능이 저하될 수 있음.

2. SQL 통계 정보 (Count, Rows)와 Call 단계의 관계

DB 성능 분석을 할 때 V$SQL, V$SESSION, V$SQLAREA 등의 뷰에서 SQL 실행 통계를 확인할 수 있어.

항목의미Call 단계와의 관계
PARSE COUNT SQL이 파싱된 횟수 Parse 단계에서 실행
EXECUTE COUNT SQL이 실행된 횟수 Execute 단계에서 실행
FETCH COUNT SQL이 데이터를 가져온 횟수 Fetch 단계에서 실행
ROWS RETURNED 조회된 행 개수 Fetch 단계에서 데이터 크기 확인 가능

🔹 예제

sql
복사편집
SELECT sql_id, executions, fetches, rows_processed FROM v$sql WHERE sql_text LIKE '%SELECT%';
  • EXECUTIONS: SQL이 실행된 횟수 (Execute 단계)
  • FETCHES: 데이터를 가져온 횟수 (Fetch 단계)
  • ROWS_PROCESSED: 실제 처리된 행 개수 (Fetch 단계에서 얼마나 많은 데이터가 조회되었는지)

3. 다중 처리 (Array Processing)

SQL을 실행할 때 한 번에 여러 개의 데이터를 처리하는 방식을 **Array Processing(배치 처리, Bulk Processing)**이라고 해.

1) 다중 처리의 필요성

  • 기본적으로 SQL을 실행할 때 한 번에 한 행(Row)씩 처리하면 성능이 저하됨.
  • 다중 처리를 사용하면 한 번의 SQL 실행으로 여러 개의 데이터를 한꺼번에 처리할 수 있음.

2) 다중 처리 방식

  1. Bulk Collect (PL/SQL에서 사용)
    • 여러 행을 한 번에 메모리로 가져와서 처리하는 방식
    • FETCH BULK COLLECT INTO 사용
    sql
    복사편집
    DECLARE TYPE t_emp IS TABLE OF employees%ROWTYPE; v_emp t_emp; BEGIN SELECT * BULK COLLECT INTO v_emp FROM employees WHERE department_id = 10; END;
    • 장점: 여러 개의 행을 한꺼번에 가져오므로 FETCH 횟수를 줄여 네트워크 오버헤드 감소
    • 단점: 너무 많은 데이터를 한 번에 가져오면 메모리 사용량이 증가할 수 있음
  2. FORALL (PL/SQL에서 사용)
    • 다중 INSERT, UPDATE, DELETE를 수행할 때 한 번에 여러 개의 행을 처리하는 방식
    • FORALL을 사용하여 반복 실행
    sql
    복사편집
    DECLARE TYPE t_emp_id IS TABLE OF employees.employee_id%TYPE; v_emp_id t_emp_id := t_emp_id(101, 102, 103); BEGIN FORALL i IN 1..v_emp_id.COUNT DELETE FROM employees WHERE employee_id = v_emp_id(i); END;
    • 장점: 여러 개의 DML 문을 한 번에 실행하여 EXECUTE 호출 횟수를 줄임
    • 단점: 예외 처리를 잘해야 함 (개별 실행보다 디버깅이 어려울 수 있음)
  3. JDBC Batch Processing (Java에서 사용)
    • Java에서 PreparedStatement.addBatch()를 사용하여 여러 개의 SQL을 한 번에 실행
    java
    복사편집
    Connection conn = DriverManager.getConnection(DB_URL, USER, PASS); PreparedStatement pstmt = conn.prepareStatement("INSERT INTO employees (id, name) VALUES (?, ?)"); for (int i = 1; i <= 1000; i++) { pstmt.setInt(1, i); pstmt.setString(2, "Employee" + i); pstmt.addBatch(); // 배치 추가 } pstmt.executeBatch(); // 한 번에 실행
    • 장점: 네트워크 오버헤드를 줄이고 성능 향상
    • 단점: 트랜잭션 관리 필요 (중간에 실패할 경우 롤백 전략 필요)

4. 정리

  • SQL 성능 통계 정보 분석 시 중요한 Call 단계
    • Parse (파싱): SQL을 분석하고 실행 계획을 수립하는 단계
    • Execute (실행): SQL을 실행하는 단계
    • Fetch (데이터 조회): 조회된 데이터를 클라이언트로 반환하는 단계
  • Call 통계 정보와의 관계
    • PARSE COUNT → SQL 실행 계획이 몇 번 생성되었는지
    • EXECUTE COUNT → SQL이 몇 번 실행되었는지
    • FETCH COUNT → 데이터를 가져오는 횟수
    • ROWS RETURNED → 실제 반환된 행 수
  • 다중 처리 (Array Processing)의 장점
    • 여러 개의 SQL을 한 번에 실행하여 네트워크 오버헤드 감소 및 성능 향상
    • Bulk Collect, FORALL, JDBC Batch Processing 등의 기법 사용 가능

 

728x90

관련 문제 풀기 

이 문제는 SQL 실행 통계 정보를 분석하는 문제야.
각 통계 값을 하나씩 분석하면서 보기가 왜 맞거나 틀렸는지 상세하게 설명할게.


1. SQL 실행 통계 정보 분석

각 Call 단계별 값 분석

callcountcpuelapseddiskquerycurrentrows
Parse 1 0.04 0.08 0 3 0 0
Execute 100 0.09 0.09 0 0 0 0
Fetch 100 6.54 6.71 12 12,510 567 100
total 201 6.67 6.88 12 12,513 567 100

2. 각 보기 분석

(1) Fetch Count(100)과 Rows(100)가 동일 → ARRAY PROCESSING을 사용했을까?

보기 ①: Fetch Count와 Rows의 수가 동일한 것을 보아 다중 처리(Array Processing)로 SQL을 수행하지 않았다.

  • Fetch Count(100) = Rows(100) → 한 번의 Fetch에 하나의 Row를 가져왔다는 의미
  • **Array Processing(배치 처리)**는 한 번의 Fetch에서 여러 개의 Row를 가져오는 방식임.
  • 그런데 여기서는 Fetch 100번 수행해서 100개의 Row를 가져왔으므로 Array Processing을 사용하지 않은 것이 맞다.
    보기 ①은 맞음.

(2) Execute Count(100)이 Parse Count(1)의 배수 → Loop 안에서 반복 실행했을까?

보기 ②: Execute Count가 Parse Count의 배수인 것으로 보아 Loop 내에서 반복 수행되었다.

  • Parse Count(1), Execute Count(100) → SQL이 한 번만 파싱되고 100번 실행되었다.
  • 이는 애플리케이션 코드 내에서 반복문(Loop)으로 같은 SQL을 여러 번 실행했음을 의미함.
    보기 ②는 맞음.

(3) SQL 실행 시간이 한 번당 0.07초 소요되었을까?

보기 ③: SQL이 한 번 실행할 때마다 0.07초 정도 소요되었다.

  • 총 실행 시간(elapsed time) = 6.88초
  • SQL 총 실행 횟수 = 100 (Execute Count)
  • 그러면 6.88초 ÷ 100 = 0.0688초

즉, SQL 한 번 실행하는 데 약 0.07초가 걸렸다고 볼 수 있음.
보기 ③은 맞음.


(4) SQL이 여러 번 실행되었지만, Parse는 한 번만 수행되었으므로 Shared SQL Area를 사용했을까?

보기 ④: 애플리케이션이 여러 번 수행되었지만 실제로 SQL을 파싱하지 않고 Shared SQL Area에서 찾아왔다.

  • Parse Count = 1, Execute Count = 100 → 한 번만 파싱되고 SQL 실행 계획을 재사용했다는 의미
  • 이는 Soft Parse가 발생했고, Shared SQL Area를 사용했을 가능성이 높음.
    보기 ④도 맞음.

3. 최종 정답: "부적절한 분석"을 찾는 문제이므로 보기가 모두 맞아서 정답 없음.

  • 문제는 **"부적절한 분석이 무엇인가?"**를 묻고 있지만,
  • 보기 ①, ②, ③, ④ 모두 적절한 분석임.
  • 만약 보기 ①이 "Array Processing을 사용했다"라고 나왔다면 틀린 보기였을 것.

4. 정리

SQL 실행 통계 정보에서 확인할 수 있는 것

  • Parse Count < Execute CountSQL이 반복 실행되었고, 실행 계획을 재사용(SHARED SQL AREA 활용)
  • Fetch Count와 Rows 개수 동일Array Processing 미사용
  • Elapsed Time ÷ Execute CountSQL 한 번 실행하는 데 걸리는 시간 계산 가능
  • Disk I/O, Query, Current 값성능 병목이 발생하는 부분 분석 가능

 

답안지에서 정답은 4번이래. 왜냐면 애플리케이션이 한번만 수행된 경우라고 하는데?
이게 애플리케이션 커서와도 관련이 있어? 참고로 커서에 대한 설명도 같이 해줘

정답이 ④번인 이유를 정확히 설명하면서, 커서(Cursor) 개념과 함께 애플리케이션 커서까지 연결해서 설명할게.


1. SQL 실행 통계 분석 (다시 확인)

앞에서 분석한 내용을 다시 한 번 정리하면,

  • Parse Count = 1 → SQL이 단 한 번만 파싱됨
  • Execute Count = 100 → SQL이 100번 실행됨 (반복 수행)
  • Fetch Count = 100, Rows = 100 → 한 번에 한 줄씩 Fetch됨, Array Processing 미사용
  • 총 실행 시간 6.88초, SQL 한 번 실행당 약 0.07초 소요됨

즉, 같은 SQL이 반복 실행되었지만, 실행 계획은 재사용되었음.


2. 정답이 ④번인 이유 (애플리케이션이 한 번만 수행된 경우?)

④번 보기: "애플리케이션이 여러 번 수행되었지만 실제로 SQL을 파싱하지 않고 Shared SQL Area에서 찾아왔다."

✅ Parse Count = 1 → SQL이 한 번만 파싱되었다.
✅ Execute Count = 100 → 같은 SQL이 100번 실행되었다.
🔴 그렇다면 애플리케이션이 여러 번 실행된 걸까?

여기서 애플리케이션이 여러 번 수행되었는지, 한 번만 수행되었는지를 구분해야 해.

  • **"애플리케이션이 여러 번 수행되었다"**는 의미는,
    • 애플리케이션이 여러 개의 세션을 열어서 같은 SQL을 실행했다는 뜻.
    • 즉, 애플리케이션이 실행될 때마다 새로운 커넥션이 생성되고, SQL이 실행됨.
    • 이 경우, 보통 Parse Count도 증가하는 경향이 있음.
  • **"애플리케이션이 한 번만 수행되었다"**는 의미는,
    • 하나의 애플리케이션 실행에서 동일 SQL을 반복 실행한 것.
    • 즉, 애플리케이션이 처음 실행될 때 SQL을 한 번만 파싱하고, 같은 SQL을 여러 번 실행한 것.
    • 이 경우, Parse Count = 1, Execute Count > 1이 나타남.

💡 따라서 여기서는 "애플리케이션이 여러 번 수행된 것이 아니라, 한 번 수행된 후 같은 SQL을 반복 실행했다"가 맞음.
🔴 ④번 보기는 "애플리케이션이 여러 번 수행되었다"고 했으므로 틀림!


3. 커서(Cursor)와 애플리케이션 커서의 관계

이제 커서(Cursor) 개념을 설명하면서, 위 내용과 어떻게 연결되는지도 볼게.

(1) 커서(Cursor)란?

커서는 SQL 실행 결과 집합을 관리하는 객체야.
즉, SQL을 실행하면 데이터베이스가 메모리에 저장해두는 결과 집합을 커서를 통해 접근할 수 있어.

커서는 크게 두 가지로 나뉘어:

1️⃣ Implicit Cursor (암시적 커서)

  • 개발자가 직접 선언하지 않아도 자동으로 생성되는 커서
  • 예: SELECT COUNT(*) FROM employees;
  • SQL 실행 후 자동으로 결과를 가져옴.

2️⃣ Explicit Cursor (명시적 커서)

  • 개발자가 직접 커서를 선언해서 사용하는 방식
  • 예: PL/SQL에서 OPEN, FETCH, CLOSE를 사용하여 명확히 커서를 관리

(2) 애플리케이션 커서(Application Cursor)란?

애플리케이션이 SQL을 실행할 때, 커서를 어떻게 관리하는지에 따라 성능에 영향을 미칠 수 있어.

  • Soft Parse (커서를 재사용)
    • SQL이 한 번만 파싱되고, 실행 계획을 재사용함.
    • Shared SQL Area에 실행 계획이 남아 있음.
    • **Parse Count = 1, Execute Count > 1**인 경우 (지금 문제의 상황!)
    • 애플리케이션이 하나의 세션에서 같은 SQL을 여러 번 실행한 경우.
  • Hard Parse (새로운 커서 생성)
    • SQL이 실행될 때마다 매번 새로운 커서가 생성됨.
    • Parse Count도 증가함.
    • 애플리케이션이 실행될 때마다 새로운 세션을 만들고 같은 SQL을 실행한 경우.

💡 즉, 문제의 상황은 Soft Parse가 발생했고, 이는 하나의 애플리케이션 내에서 반복 실행되었음을 의미함.
따라서 애플리케이션이 여러 번 실행된 것이 아니라, 한 번 실행된 후 반복 실행된 것!


4. 최종 정리 (정답: ④번이 틀린 이유)

🔹 Parse Count = 1, Execute Count = 100SQL을 한 번만 파싱하고 100번 실행했다.
🔹 이것은 애플리케이션이 여러 번 수행된 것이 아니라, 한 번 수행된 후 반복 실행한 것.
🔹 그러므로 보기 ④번 "애플리케이션이 여러 번 수행되었다"는 잘못된 분석이다!

✅ 정답: ④번 (가장 부적절한 분석)


💡 보너스: 성능 개선을 위해 고려할 것

  • 배치 처리(Array Processing) 사용 여부 확인
    • 한 번에 여러 개의 데이터를 Fetch하면 성능이 개선됨.
  • 커서 재사용 여부 확인 (Soft Parse 활용)
    • Hard Parse를 최소화해야 성능이 향상됨.
  • SQL 실행 횟수를 줄이는 방법 고려
    • 필요하면 SQL을 합치거나, Index를 활용하여 실행 횟수를 줄이는 것도 가능함.
728x90