목록개발 독서 스터디/친절한 SQL 튜닝 (10)
seoyyyy-dev

1. 통계정보와 비용 계산 원리1.1 선택도와 카디널리티 🥸 선택도(Selectivity) = 전체 레코드 중에서 조건절에 의해 선택되는 레코드 비율 = 1 / NDV(컬럼 값 종류 개수: Number of Distinct Values)🥸카디널리티(Cardinality) = 전체 레코드 중에서 조건절에 의해 선택되는 레코드 개수 = 총 로우 수 x 선택도 = 총 로우 수 / NDV 예제)상품분류 컬럼에 '가전', '의류', '식재료', '생활용품' 네 개의 값이 있을 때 아래 조건절에 의한 선택도는 25%(1/4)이며, 전체 레코드가 10만 건이라고 가정하면 카디널리티는 2만 5천이다.WHERE 상품분류 = '가전'1 / 4 (NDV = '가전', '의류', '식재료', '생활용품') ..

3. 파티션을 활용한 DML 튜닝3.1 테이블 파티션파티셔닝(Partitioning)은 테이블 또는 인덱스 데이터를 특정 컬럼(파티션 키) 값에 따라 별도 세그먼트에 나눠서 저장하는 것을 의미일반적으로 시계열에 따라 Range 방식으로 분할하며, 그 외의 다른 기준으로 분할할 수도 있다. (ex. 월별, 분기별, 계절별 등등 ...) 😊 파티션이 필요한 이유 ▶️ 관리적 측면: 파티션 단위 백업, 추가, 삭제, 변경으로 가용성 향상 ▶️ 성능적 측면: 파티션 단위 조회 및 DML, 경합 또는 부하 분산 😊 파티션 종류 1️⃣ Range 파티션 2️⃣ 해시 3️⃣ 리스트 1️⃣ Range 파티션오라클 8 버전부터 제공되는 기초적 방식으로 주로 날짜 컬럼을 기준으로 파티셔닝한다.create..

1. 기본 DML 튜닝1.1 DML 성능에 영향을 미치는 요소 ✔️ 인덱스 ✔️ 무결성 제약 ✔️ 조건절 ✔️ 서브쿼리 ✔️ Redo 로깅 ✔️ Undo 로깅 ✔️ Lock ✔️ 커밋 테이블에 레코드 입력(Insert) 시 인덱스에도 입력을 해야하며, 테이블은 Freelist를 통해 입력할 블록을 할당받지만 인덱스는 정렬된 자료구조이므로 수직적 탐색을 통해 입력할 블록을 찾아야한다. Delete 할 때도 마찬가지로 테이블에서 레코드 하나를 삭제 시 인덱스 레코드를 모두 찾아서 삭제해 줘야 한다.Update 시는 변경된 컬럼을 참조하는 인덱스만 찾아서 변경을 해주되 대신 테이블에서 한 건 변경 시 인덱스에는 삭제 후 삽입하는 식으로 두 개의 오퍼레이션이 발생한다. ⭐ Freelist: 테이..

1. 소트 연산에 대한 이해1.1 소트 수행 과정- 소트는 기본적으로 PGA에 할당한 Sort Area에서 이루어지며 메모리 공간인 Sort Area가 다 차면 디스크 Temp 테이블스페이스를 활용한다. 😎 소트 연산의 두가지 유형 ▶️ 메모리 소트(In-Memory Sort) : 전체 데이터의 정렬 작업을 메모리 내에서 완료하는 것. 'Internal Sort'라고도 함 ▶️ 디스크 소트(To-Disk Sort) : 할당받은 Sort Area 내에서 정렬을 완료하지 못해 디스크 공간까지 사용함. 'External Sort' 라고도 함🙂 디스크 소트 과정 1️⃣ 소트할 대상 집합을 SGA 버퍼캐시를 통해 읽어들이고, Sort Area에서 정렬을 시도한다. 2️⃣ Sort Area만으로는 양이 ..

1. NL 조인(Nested Loop Join)1.1 기본 메커니즘NL 조인의 기본 메커니즘을 알아보기 위해 아래 사원과 고객테이블을 이용하여 1996년 1월 1일 이후 입사한 사원이 관리하는 고객 데이터를 추출하는 프로그램을 작성해 보자. 위의 조건을 SQL로 만든다면 아래와 같이 두 테이블을 조인하여 쿼리를 쉽게 작성할 수 있다. select e.사원명, c.고객명, c.전화번호from 사원 e, 고객 cwhere e.입사일자 >= '19960101'and c.관리사원번호 = e.사원번호 위의 SQL을 C, JAVA, PL/SQL 와 같은 언어로 프로그래밍한다고 하면 아래와 같이 중첩 루프문(Nested Loop) 수행 구조를 이용하게 된다. /** C, JAVA 의 경우 **/for(i = 0; i..

4 인덱스 설계4.1 인덱스 설계가 어려운 이유SQL 최적화를 위해 테이블마다 인덱스를 수십개씩 남발해서 생성하다보면 여러 문제가 발생할 수 있다.하나의 테이블에 인덱스가 여섯개 달려있으면 데이터의 입력/삭제 시 여섯 개 인덱스에도 전부 데이터를 입력/삭제해야 한다.또한 테이블과 달리 인덱스는 정렬 상태를 유지해야 하므로 수직적 탐색을 통해 입력할 블록부터 찾고, 찾은 블록에 여유 공간이 없을 시 인덱스 분할(Index Split)도 발생한다. 1️⃣DML 성능 저하 (➡️ TPS(초당 처리되는 트랜잭션 수) 저하) 2️⃣데이터베이스 사이즈 증가 (➡️ 디스크 공간 낭비) 3️⃣데이터베이스 관리 및 운영 비용 상승 😣 개발 단계에서 최적 인덱스 설계의 중요성시스템 개발 단계에서는 비교적 쉽게 인..

3. 인덱스 스캔 효율화3.1 인덱스 탐색 인덱스 스캔 효율화 튜닝을 이해하기 위해 여러 조건절에 따른 인덱스 탐색 과정을 분석해보자 위 그림은 루트 블록에 C1, C2 컬럼인 레코드 세개가 있고, 각 레코드는 하위노드를 가리키는 블록 주소를 갖는다. WHERE C1 = 'B' 조건절 1은 수직적 탐색을 통해 C1 = 'B' 인 첫번째 레코드를 찾고 'C'를 만나는 순간 스캔을 멈춘다.주의할 점은 루트 블록 스캔 과정에서 C1 = 'B'인 레코드를 찾을 때 그것이 가리키는 리프 블록 3으로 내려가면 안되고 그 직전 레코드가 가리키는 리프블록 2로 내려가서 스캔 시작점을 찾는다. WHERE C1 = 'B'AND C2 = 3 조건절 2도 수직적 탐색을 통해 C1 = 'B' 이고 C2 = 3인 첫번 째 레..

1. 테이블 액세스 최소화1.1 테이블 랜덤 액세스 - SQL 이 참조하는 컬럼을 인덱스가 모두 포함하지 않는다면 인덱스를 스캔한 후 반드시 테이블을 액세스하게 되는데 실행계획에서는 'TABLE ACCESS BY INDEX ROWID' 라고 표시된다. - 인덱스를 스캔하는 이유는 검색조건을 만족하는 소량의 데이터를 인덱스에서 빨리 찾고 거기서 테이블 레코드를 찾아가기 위한 주소값, 즉 ROWID를 얻으려는데 있다.😀인덱스 ROWID는 물리적 주소일까? 논리적 주소일까? - 인덱스 ROWID는 논리적 주소이다. - ROWID는 프로그래밍의 포인터와는 다른개념이며, 테이블 레코드와 물리적으로 직접 연결된 구조가 아니다. - 디스크 상에서 테이블 레코드를 찾아가기 위한 논리적 주소 정..