인덱스와 DML 성능
INSERT, DELETE
인덱스는 정렬된 자료구조이므로 자리를 찾아가서 작업해야한다.
UPDATE
변경된 컬럼을 참조하는 인덱스만 찾아서 변경하면 된다(인덱스에 포함된 정보가 변경됐을 때만)
하지만 이 경우는 정렬을 맞춰줘야하기 때문에 이전 인덱스 정보 삭제 후 삽입하는 두 개의 오퍼레이션 발생한다.
무결성제약과 DML 성능
PK, FK 제약은 Check, Not Null 과 다르게 실제 데이터를 조회해봐야하기 때문에 성능에 더 큰 영향을 미친다.
Redo 로깅
Redo 로그는 트랜잭션 데이터가 유실됐을 때 트랜잭션을 재현함으로써 유실 이전 상태로 복구하는데 사용
Redo 로그의 용도는 아래와 같다.
Database Recovery
물리적으로 디스크가 깨지는 Media Fail 발생시 데이터베이스 복구를 위해 사용
Cache Recovery
버퍼캐시에 저장된 변경사항이 디스크 상의 데이터 블록에 아직 기록되지 않은 상태에서 인스턴스가 비정상적으로 종료될 대 트랜잭션 데이터 유실에 대비하기 위해 사용
Fast Commit
변경된 메모리 버퍼블록을 디스크 상의 데이터 블록에 반영하는 작업은 랜덤 액세스 방식으로 이루어지므로 매우 느림.
반면 로그는 Append 방식으로 기록하므로 상대적으로 빠르다. 버퍼캐시 블록에만 기록된채 아직 디스크에 기록되지 않았지만 Redo 로그를 믿고 빠르게 커밋을 완료한다.
Undo 로깅
Undo는 트랜잭션을 롤백함으로써 현재를 과거 상태로 되돌리는데 사용
Undo의 용도는 다음과 같다
Transatcion Rollback
트랜잭션에 의한 변경사항을 최종 커밋하지 않고 롤백하고자 할 때 Undo 데이터 사용
Transaction Recovery
시스템이 셧다운된 시점에 아직 커밋되지 않았던 트랜잭션들을 모두 롤백해야할 때 Undo 데이터 사용
Read Consistency
읽기 일관성을 위해 제공, MVCC 모델에선 select 시 블록 SCN을 쿼리 SCN보다 크면 블록SCN을 Undo 데이터를 적용해 쿼리가 시작된 시점으로 돌려서 읽음
Commit 과 DML 성능
트랜잭션이 데이터를 변경하고 커밋하는 과정, 변경된 블록을 데이터 파일에 기록하는 과정은 다음과 같다.
- DML 문을 실행하면 Redo 로그버퍼에 변경사항을 기록
- 버퍼블록에서 데이터를 변경, 버퍼캐시에서 블록을 찾지 못하면 데이터파일에서 읽는 작업부터 진행
- 커밋
- LGWR 프로세스가 Redo 로그버퍼 내용을 로그파일에 일괄저장
- DBWR 프로세스가 변경된 버퍼 블록들은 데이터파일에 일괄저장
오라클은 데이터 변경 전에 항상 로그부터 기록(1-2, 4-5)
Q. 버퍼캐시가 휘발성이라 Redo 로그에 기록하는데 Redo 버퍼도 휘발성인데 커밋한 트랜잭션의 영속성을 어떻게 보장?
LGWR 프로세스는 '적어도 커밋시점에는' Redo 로그버퍼 내용을 로그파일에 기록한다.
해당 작업은 디스크 I/O 작업이고 작업이 완료되야 서버프로스세스가 다음 작업을 진행(Sync 작업)할 수 있다.
데이터베이스 Call
Parse Call
SQL 파싱과 최적화를 수행하는 단계, SQL과 실행 계획을 라이브러리 캐시에서 찾으면(소프트 파싱) 최적화 단계는 생략
Execute Call
SQL 실행하는 단계, DML은 이 단계에서 끝나지만 select는 Fetch 단계를 거친다.
Fetch Call
데이터를 읽어 사용자에게 결과집합을 전송하는 과정. 전송할 데이터가 많을 때는 Fetch Call이 여러번 발생

User Call
네트워크를 경유해 DBMS 외부로부터 인입되는 Call
Recursive Call
DBMS 내부에서 발생하는 Call. SQl 파싱과 최적화 과정에서 발생하는 데이터 딕셔너리 조회, Pl.SQL로 작성한 사용자 정의함수/프로시저/트리거에 내장된 SQL 실행할 때 발생하는 Call
어떤 Call(User, Recursive)이든 SQL을 실행할 때 마다 Parse, Execute, Fetch Call 단계를 거친다.
Call은 최대한 줄일 것
절차적 업무를 위해 PL/SQL를 사용하거나 서버단에서 로직을 분리하고 여러번 쿼리 Call(JPA N+1 문제와 같은)을 하는 것은 성능에 좋지 않다. 가능하면 One SQL 처리할 것
Array Processing 활용
그럼에도 복잡한 업무 로직을 포함하기에 PL/SQL, 서버단에서 로직을 분리해 처리할 때는 Arry Processing 기능을 활용해 Call을 줄일 것