' SQL 자격검정 실전문제 ' (일명 노랭이책)을 풀어가며 핵심 개념을 정리한 글입니다.
🔍 1 - 1 데이터 모델링의 이해
- 데이터 모델링이 필요한 이유
- 업무 정보를 구성하는 기초가 되는 정보들에 대해 일정한 표기법에 의해 표현
- 분석된 모델을 가지고 실제 데이터베이스를 생성하여 개발 및 데이터 관리에 사용
- 데이터모델링 자체로서 업무의 흐름을 설명하고 분석하는 부분에 의미를 가지고 있다.
- 데이터 모델링의 특징
- 추상화 : 현실을 일정한 형식에 맞춰 간략하게 표현
- 단순화 : 누구나 이해하기 쉽도록 표현
- 명확화 : 애매모호함을 배제하고 명확하게 한 가지 의미를 갖도록 표현
- 데이터 모델링의 유의점
- 중복 : 여러 장소에 같은 정보 저장 X
- 비유연성 : 데이터 정의, 데이터 사용 프로세스 분리
- 데이터 혹은 프로세스의 작은 변화 → 애플리케이션 및 데이터베이스에 중대한 변화를 일으킬 수 있는 가능성을 줄임
- 비일관성 : 데이터와 데이터 간 상호 연관 관계에 대해 명확히 정의 (연계성을 낮춤)
- 데이터 모델링의 개념
- 개념적 데이터 모델 : 추상화 수준 ↑, 업무중심적 , 포괄적 , 전사적 데이터 모델링이나 EA 수립시 많이 사용
- 논리적 데이터 모델 : 구축하고자 하는 업무에 대해 Key, 속성, 관계 등을 정확하게 표현, 재사용성 ↑
- 물리적 데이터 모델 : 실제 데이터베이스에 이식할 수 있도록 성능, 저장 등 물리적 성격 고려
- 데이터 모델링의 관계에 대한 개념
- 데이터 모델링에는 존재적 관계와 행위에 의한 관계를 구분하는 표기법이 없다.
- UML에서는 연관관계와 의존관계에 대해 다른 표기법을 가진다.
- 관계 표기법 요소 : 관계명 , 관계차수, 선택사양
- 데이터베이스 스키마 구조
- 외부스키마 : View 단계 여러 개의 사용자 관점으로 구성
- 개념스키마 : 모든 사용자 관점을 통합한 조직 전체의 DB 기술, DB에 저장되는 데이터와 그들 간의 관계 표현
- 내부스키마 : DB가 물리적으로 저장된 형식, 데이터가 실제로 저장되는 방법 표현
- 엔티티 특징
- 해당 업무에서 필요하고 관리하고자 하는 정보여야 함
- 유일한 식별자에 의해 식별이 가능해야 함
- 영속적으로 존재하는 두 개 이상의 인스턴스 집합이어야 함
- 업무 프로세스에 의해 이용되어야 함
- 반드시 속성이 있어야 함
- 다른 엔티티와 최소 한 개 이상의 관계가 있어야 함
- 관계 도출
- 두 개의 엔티티 사이에 관심있는 연관규칙이 존재하는가 ?
- 두 개의 엔티티 사이에 정보의 조합이 발생되는가 ?
- 업무기술서, 장표에 관계 연결에 대한 규칙이 서술되어 있는가 ?
- 업무기술서, 장표에 관계 연결을 가능하게 하는 동사가 있는가 ?
- 식별자의 종류
- 대표성 여부 : 주식별자 vs 보조식별자
- 주식별자의 특징
- 유일성 : 엔티티 내 모든 인스턴스 유일하게 구분
- 최소성 : 속성 수는 유일성을 만족하는 최소의 수
- 불변성 : 식별자 값은 변하지 않아야 함
- 존재성 : 주식별자 지정되면, 반드시 데이터 값이 존재해야 함
- 대표성 : 주식별자는 엔티티를 대표할 수 있어야 한다.
- 엔티티 내 스스로 생성 여부 : 내부식별자 vs 외부식별자
- 속성의 수 : 단일식별자 vs 복합식별자
- 대체 여부 : 본질식별자 vs 인조식별자
- 대표성 여부 : 주식별자 vs 보조식별자
- 식별자와 비식별자
- 식별자
- 강한 연결, 자식 주식별자의 구성에 포함, 실선 표현
- 반드시 부모 엔티티에 종속
- 비식별자
- 약한 관계, 자식 일반 속성에 포함, 점선 표현
- 자식 주식별자를 독립으로 구성
- 식별자
- 속성의 분류
- 속성의 특성에 따른 분류
- 기본속성 : 제품이름, 제조년월, 제조원가
- 설계속성 : 약품 용기 코드
- 파생속성 : 계산값
- 엔티티 구성 방식에 따른 분류
- PK
- FK
- 일반속성
- 속성의 특성에 따른 분류
🔍 1 - 2 데이터 모델과 성능
- 성능 데이터 모델링 특징
- 데이터의 증가가 빠를수록 성능저하에 따른 성능 개선 비용은 증가한다.
- 데이터모델은 성능을 튜닝하면서 변경이 될 수 있는 특징이 있다.
- 분석/설계 단계에서 성능을 고려한 데이터모델링을 수행할 경우 성능 저하에 따른 Rework 비용을 최소화 할 수 있는 기회를 가지게 된다.
- 성능 데이터 모델링 수행 절차
- 데이터 모델링을 할 때 정규화를 정확하게 수행
- 데이터베이스 용량 산정 수행
- 데이터베이스에 발생되는 트랜잭션 유형 파악
- 용량과 트랜잭션 유형에 따라 반정규화 수행
- 이력모델의 조정, PK/FK 조정, 슈퍼타입/서브타입 조정 등 수행
- 성능 관점에서 데이터모델 검증
- → 정용트반조데
- 반정규화
- 데이터를 중복, 통합, 분리하여 성능을 향상시키기 위한 기법
- 반정규화 수행
- 데이터를 조회할 때 디스크 I/O량이 많아 성능 저하 예상
- 경로가 너무 멀어 조인으로 인한 성능 저하 예상
- 칼럼을 계산하여 읽을 때 성능이 저하 예상
💡 반정규화 판단 요소
- 재현의 적시성 (빠르게 처리)
- 조회 시 I/O 량이 많아 성능 저하가 있는 경우
- 경로가 너무 멀어 조인으로 인한 성능 저하가 예상되는 경우
- 컬럼을 읽을 때 성능이 저하될 것이 예상되는 경우
다량의 데이터 탐색의 경우 인덱스가 아닌 파티션 및 데이터 클러스터링 등의 다양한 물리 저장 기법을 활용하여 성능 개선을 유도할 수 있다. (다량의 데이터를 탐색하는 처리가 반복적으로 빈번하게 발생한다면 이때는 반정규화를 고려하는 것이 좋음)
이전 또는 이후 위치의 레코드에 대한 탐색은 window function 등으로 접근 가능하다. 또한 집계 테이블 이외에도 다양한 유형 (다수 테이블의 키 연결 테이블 등)에 대하여 반정규화 테이블 적용이 필요할 수 있다.
- 테이블 반정규화
- 테이블 병합 : 1:1 관계 병합, 1:M 관계 병합, 슈퍼/서브타입 병합
- 테이블 분할 : 수직 분할, 수평 분할
- 테이블 추가 : 중복 , 통계 , 이력 , 부분 테이블 추가
- 칼럼 반정규화
- 중복 칼럼, 파생 칼럼, 이럭테이블 칼럼, PK에 의한 칼럼, 응용 시스템 오동작을 위한 칼럼 추가
- 칼럼수가 많은 테이블
- 로우체이닝이 발생할 정도로 많은 컬렘이 한 테이블에 존재할 경우 조회성능 저하가 발생할 수 있다.
- 트랜잭션이 접근하는 칼럼유형을 분석하여 1:1로 테이블을 분리하면 디스크I/O가 줄어들어 조회 성능을 향상 시킬 수 있다.
- 다른 방법으로 처리 (성능 향상)
- 지나치게 많은 조인 → 뷰 사용
- 대량의 데이터 처리나 부분 처리에 의한 성능 저하 → 클러스터링 적용 or 인덱스 조정
- 대량의 데이터 → 파티셔닝 기법 (PK 성격에 따라 부분적인 테이블로 분리)
- 응용 애플리케이션에서 로직 구사 방법 변경
- 슈퍼/서브 타입 데이터 모델
- 개별로 발생되는 트랜잭션 → 개별 테이블로 구성
- 슈퍼 + 서브타입의 트랜잭션 → 슈퍼 + 서브타입 테이블로 구성
- 전체를 하나로 묶어 트랜잭션 발생 → 하나의 테이블로 구성
- FK에 대한 개념
- 엔티티간 논리적 관계가 있을 경우 FK Constraints를 생성했는지 여부와 상관없이 조인 성능을 향상 시키기 위한 인덱스를 생성해주는 것이 좋다.
- 분산 데이터베이스
- 장점
- 지역 자치성, 점증적 시스템 용량 확장, 신뢰성과 가용성, 효용성과 융통성
- 빠른 응답 속도, 통신 비용 절감, 시스템 규모의 적절한 조절, 각 지역 사용자의 요구 수용 증대
- 공통 코드, 기준 정보 등 마스터 데이터를 분산 환경에 복제 분산
- 실시간 업무적 특성, 백업 사이트 구성
- 단점
- 소프트웨어 개발 비용, 오류의 잠재성 증대, 처리 비용의 증대, 설계 관리의 복잡성과 비용
- 불규칙한 응답 속도, 통제의 어려움, 데이터 무결성에 대한 위협
- 장점
GSI (Global Single Instance) : 통합된 한 개의 인스턴스 (통합 데이터베이스 구조)
🔍 2 - 1 SQL 기본
- SQL 문장 종류
- DML (데이터 조작어) : SELECT, INSERT, UPDATE, DELETE ( SUID )
- 비절차적 : 무슨(what) 데이터를 원하는지만 명세
- 절차적 : 어떻게(how) 데이터를 접근해야 하는지 명세
- DDL (데이터 정의어) : CREATE, ALTER, DROP, RENAME (CARD)
- DCL (데이터 제어어) : GRANT , REVOKE
- TCL (트랜잭션 제어어) : COMMIT , ROLLBACK, SAVEPOINT
- 트랜잭션 : 데이터베이스의 논리적 연산단위, 밀접히 관련되어 분리될 수 없는 한 개 이상의 데이터베이스 조작
- DML (데이터 조작어) : SELECT, INSERT, UPDATE, DELETE ( SUID )
- 제약조건 종류
- PRIMARY KEY (기본키) : UNIQUE & NOT NULL
- UNIQUE KEY (고유키) : 중복값 없음, null 가능
- NOT NULL
- CHECK
- FOREIGN KEY (외래키) : null 가능, 참조 무결성 제약
- 참조 동작
- DELETE/MODIFY
- CASCADE : 부모 삭제 시 자식 같이 삭제
- SET NULL : 부모 삭제 시 자식 해당 필드 NULL
- SET DEFAULT : 부모 삭제 시 자식 해당 필드 Default 값
- RESTRICT : 자식 테이블에 PK 값이 없는 경우에만 부모 삭제 허용
- INSERT
- AUTOMATIC : 부모 테이블에 PK가 없는 경우 부모 PK 생성 후 자식 입력
- SET NULL : 부모 테이블에 PK가 없는 경우 자식 외부키를 null
- SET DEFAULT : 부모 테이블에 PK가 없는 경우 자식 외부키를 Default 값
- DEPENDENT : 부모 테이블에 PK가 존재할 때만 Child 입력 허용
- DELETE/MODIFY
- 삭제
- DROP
- DDL, Auto Commit (Rollback 불가능)
- 테이블 정의 자체를 완전히 삭제, 테이블이 사용했던 스토리지 모두 release
- TRUNCATE
- DDL (일부 DML), Auto Commit (Rollback 불가능)
- 테이블을 최초로 생성된 초기상태로 만듦, 최초 테이블 생성 시 할당된 스토리지만 남기고 release
- DELETE
- DML, 사용자 Commit (Commit, Rollback 가능)
- 데이터만 삭제, 사용했던 스토리지는 release 되지 않음
- 트랜잭션 로그 보관
- DROP
- 데이터베이스 트랜잭션
- 원자성(Atomicity) : 트랜잭션에서 정의된 연산들은 모두 성공적 실행 or 전혀 실행되지 않은 상태로 남아있어야 함
- 일관성(Consistency) : 트랜잭션이 실행되기 전 데이터베이스 내용이 잘못되어 있지 않다면 트랜잭션이 실행된 이후에도 데이터베이스의 내용에 잘못이 있으면 안됨
- 고립성(Isolation) : 트랜잭션이 실행되는 도중 다른 트랜잭션의 영향을 받아 잘못된 결과를 만들어서는 안됨
- 지속성(durability) : 트랜잭션이 성공적으로 수행되면 그 트랜잭션이 갱신한 데이터베이스의 내용은 영구적으로 저장됨
- 트랜잭션 문제점
- Dirty Read : 다른 트랜잭션에 의해 수정되었지만 아직 커밋되지 않은 데이터를 읽는 것
- Non-Repeatable Read : 한 트랜잭션 내에서 같은 쿼리를 두 번 수행했는데, 그 사이에 다른 트랜잭션이 값을 수정 또는 삭제하는 바람에 두 쿼리 결과가 다르게 나타나는 현상
- Phantom Read : 한 트랜잭션 내에서 같은 쿼리를 두 번 수행했는데, 첫 번째 쿼리에서 없던 유령 레코드가 두 번째 쿼리에서 나타나는 현상
- Oracle vs SQL Server
- Oracle
- DDL 문장 자동 Commit 수행
- NULL 조회 : 컬럼 IS NULL
- NULL 값이 가장 큰 값
- SQL Server
- DDL 문장 자동 Commit 수행 X
- NULL 조회 : 칼럼 = ''
- NULL 값이 가장 작은 값
- Oracle
- 단일행 문자열 함수
- CHR/CHAR(ASCII 번호) : 문자나 숫자로 바꿈
- CHR(10) = 줄바꿈
- ASCII(문자) : 아스키 코드 번호로 바꿈
- 단일행 NULL 관련 함수
- NVL(식1, 식2) : 식1의 결과값이 NULL이면 식2 값 출력 - Oracle
- ISNULL(식1, 식2) : NVL과 동일하나, SQL Server의 함수
- NULLIF(식1, 식2) : 식1이 식2와 같으면 NULL, 같지 않으면 식1 리턴
- COALESCE(식1,식2,...) : 임의의 개수 표현식에서 NULL이 아닌 최초의 표현식, 모든 표현식이 NULL이면 NULL 리턴
- 집계 함수
- COUNT(*) : NULL 값 포함
- COUNT(표현식) : NULL 값 제외
- SUM , AVG : NULL 값 제외
- SELECT 문장 실행 순서
- FROM - WHERE - GROUP BY - HAVING - SELECT - ORDER BY
- JOIN 문장
- EQUI JOIN : WHERE 절에 JOIN 조건을 넣음
- ANSI/ISO SQL 표준 EQUI JOIN : ON 절에 JOIN을 넣음
- DBMS 옵티마이저는 FROM 절에 나열된 테이블이 아무리 많아도 항상 2개의 테이블씩 짝 지어 JOIN 수행
- PK 제약조건 생성
# PK 제약조건 생성
ALTER TABLE 테이블명 ADD CONSTRAINT 제약조건명 PRIMARY KEY (컬럼명);
# 테이블 생성시 PK 제약조건
CREATE TABLE 테이블명 (
~~, CONSTRAINT 제약조건명 PRIMARY KEY (컬럼명)
);
- 인덱스 생성
CREATE INDEX 인덱스명 ON 테이블명 (컬럼명);
- 테이블 컬럼 삭제
ALTER TABLE 테이블명
DROP COLUMN 컬럼명
- 테이블명 변경
RENAME 기존 테이블명 TO 변경 테이블명
- CASE 문장
# SIMPLE_CASE_EXPRESSION
CASE WHEN 컬럼명 = '값' THEN '표현식'
# SHARCHED_CASE_EXPRESSION
CASE 컬럼명 WHEN '값' THEN '표현식'
🔍 2 - 2 SQL 활용
- 연산자 우선순위
우선순위 | 연산자 |
1 | 산술 연산자(*,/,+,-) |
2 | 연결 연산자 ( || ) |
3 | 비교 연산자(<, >, >= , <=) |
4 | IS NULL, LIKE , IN |
5 | BETWEEN |
6 | NOT |
7 | AND |
`8 | OR |
- 순수 관계 연산자
- SELECT , PROJECT , JOIN , DIVIDE (SPJD)
- JOIN 조건
- ON (A.id = B.id)
- USING(id)
- OUTER JOIN
# LEFT OUTER JOIN
SELECT X.KEY1, Y.KEY2
FROM TBL1 X LEFT JOIN TBL2 Y
ON (X.KEY1 = Y.KEY2);
# (ANSI 표준) LEFT OUTER JOIN
SELECT X.KEY1, Y.KEY2
FROM TBL1 X, TBL2 Y
WHERE X.KEY1 = Y.KEY2(+);
# RIGHT OUTER JOIN
SELECT X.KEY1 , Y.KEY2
FROM TBL1 X RIGHT OUTER JOIN TBL2 Y
ON(X.KEY1 = Y.KEY2);
# FULL OUTER JOIN
SELECT X.KEY1, Y.KEY2
FROM TBL1 X FULL OUTER JOIN TBL2 Y
ON (X.KEY1 = Y.KEY2);
- 집합 연산자
- UNION : 합집합, 중복된 행 제거
- UNION ALL : 합집합, 중복된 행도 출력
- INTERSECT : 교집합
- EXCEPT/MINUS : 차집합
- 계층 구조
- START WITH : 계층 구조 전개의 시작 위치 지정 (루트 데이터 지정)
- CONNECT BY : 현재 읽은 칼럼 지정
- PRIOR 자식 = 부모 : 부모 → 자식 방향으로 전개 (순방향)
- PRIOR 부모 = 자식 : 자식 → 부모 방향으로 전개 (역방향)
- ORDER SIBLINGS BY : 형제 노드 사이에서 정렬 수행
- 계층형 질의문
- SQL Server에서의 계층형 질의문은 CTE(Common Table Expression)를 재귀 호출함으로써 계층 구조를 전개한다.
- SQL Server에서의 계층형 질의문은 앵커 멤버를 실행하여 기본 결과 집합을 만들고 이후 재귀 멤버를 지속적으로 실행한다.
- 오라클의 계층형 질의문에서 WHERE 절은 모든 전개를 진행한 이후 필터 조건으로서 조건을 만족하는 데이터만을 추출하는데 활용된다.
- PRIOR 키워드는 SELECT, WHERE 절에서도 사용 가능하며 'PRIRO 자식 = 부모' 형태로 사용하면 순방향 전개로 수행된다.
- 서브쿼리 종류
- 반환되는 데이터 형태
- 단일행 서브쿼리 : 실행 결과가 항상 1건 이하, 단일행 비교 연산자 (= , <, >, >= , <= , <>)와 함께 사용
- 다중행 서브쿼리 : 실행 결과가 여러 건, 다중행 비교 연산자(IN, ALL, ANY, SOME, EXISTS)와 함께 사용 (단일행 비교 연산자도 사용 가능)
- 다중칼럼 서브쿼리 : 실행 결과로 여러 칼럼 반환, 동시 비교, 칼럼 개수와 칼럼 위치 동일 (SQL Server에서 지원 X)
- 사용 형태
- SELECT 절 : 스칼라 서브 쿼리, 단일행 연산 서브쿼리, JOIN으로 변경 가능
- FROM 절 : 인라인 뷰, 동적 뷰
- WHERE 절 : 다중행 연관 서브쿼리
- HAVING 절
- ORDER BY 절
- 연관 서브쿼리 : 서브쿼리가 메인쿼리 컬럼을 포함하고 있는 형태
- 비연관 서브쿼리 : 주로 메인쿼리에 값을 제공하기 위한 목적으로 사용
- 특징
- 메인 쿼리에서 서브 쿼리의 결과 칼럼을 사용할 수 없다 (반대는 가능)
- 서브 쿼리에서는 ORDER BY 를 사용하지 못한다.
- 메인 쿼리 레벨이 1이고 서브 쿼리가 M이면 항상 메인 쿼리 레벨 1로 결과 집합이 생성된다.
- 반환되는 데이터 형태
- 뷰(VIEW) 장점
- 독립성 : 테이블 구조가 변경되어도 뷰를 사용하는 응용 프로그램은 변경하지 않아도 됨
- 편리성 : 복잡한 질의를 뷰로 생성, 관련 질의를 단순하게 작성, 자주 사용하는 형태의 SQL 문
- 보안성 : 뷰 생성 시 숨기고 싶은 정보를 제외하고 작성
- 윈도우 함수 특징
- Partition과 Group by 구문은 의미적으로 유사하다.
- Partition 구문이 없으면 전체 집합을 하나의 Partition으로 정의한 것과 동일하다.
- 윈도우 함수 처리를 해도 결과 건수는 줄어들지 않는다.
- 윈도우 함수 적용 범위는 Partition을 넘을 수 없다.
- 파티셔닝
- 범위 분할(Range Partitioning)
- 분할 키 값이 범위 내 있는지 여부로 구분
- 목록 분할(List Partitioning)
- 값 목록에 파티션을 할당 분할 키 값을 그 목록에 비추어 파티션을 선택
- 해시 분할 (Hash partitioning)
- 해시 함수의 값에 따라 파티션에 포함할 지 여부를 결정
- 합성 분할 (Composite partitioning)
- 상기 기술을 결합, 먼저 범위 분할 -> 다음 해시 분할
- 범위 분할(Range Partitioning)
- 집계 그룹 함수
- ROLLUP : 계층 구조를 가진 SUB TOTAL을 생성하는 함수, 나열된 컬럼 순서 변경되면 수행 결과도 변경
- CUBE : 결합 가능한 모든 값에 대해 다차원 집게 생성
- GROUPING SETS : 계층 구조 없이 집계 출력, 순서가 바뀌어도 결과 같음, 평등 관계
- 특징
- ROLLUP, CUBE, GROUPING SETS 모두 동일한 결과를 추출할 수 있다.
- 집계 대상 컬럼 이외의 GROUP 대상 컬럼의 값은 NULL을 반환한다.
- 순위 함수
- RANK : 동일 값에 대해 동일 순위 부여, 중간 순위 비워둠
- DENSE_RANK : 동일 값에 대해 동일 순위 부여, 중간 순위 비우지 않음
- ROW_NUMBER : 동일 값에 대해 유일한 순위 부여
- ORDER BY : 전체 데이터 정렬
- PARTITION BY : 데이터 구분
- 함수
- LAG : 현재 읽혀진 데이터의 이전 값을 가져옴
- LEAD : 현재 읽혀진 데이터의 이후 값을 가져옴
- 권한 부여
- GRANT : 권한 부여
- REVOKE : 권한 회수
- ROLE : 다양한 권한을 하나의 그룹으로 묶어놓은 논리적인 권한의 그룹, 사용자와 권한 사이에서 중개 역할 수행
- PL/SQL
- Block 구조로 되어 있어 기능별로 모듈화 가능
- 변수, 상수 등을 선언하여 SQL 문장 간 값을 교환
- 절차적 언어(IF, LOOF 등)를 사용하여 절차적 프로그램이 가능하도록 함
- 프로시저 내부에 작성된 절차적 코드는 PL/SQL 엔진이 처리하고 일반적인 SQL 문장은 SQL 실행기가 처리한다.
- 저장 모듈
- 사용자 정의 함수 : 다른 SQL 문을 통해 호출되고, 그 결과를 리턴하는 보조적 역할
- 프로시저, 사용자 정의 함수 : 트랜잭션을 분할할 수 있음, 호출 프로시저 트랜잭션과 별도로 자율 트랜잭션 처리 가능
- 프로시저 : SQL을 로직과 함께 데이터베이스 내에 저장해 놓은 명령문의 집합
- EXECUTE 명령어로 실행, 트랜잭션 제어 가능
- 트리거 : DML 문이 수행되었을 때 데이터베이스에서 자동으로 동작하도록 작성된 프로그램
- 무결성과 일관성을 위해 사용, 로그인 작업에도 사용 가능
- TCL을 이용해 트랜잭션 제어가 불가능
- 사용자 정의 함수 : 다른 SQL 문을 통해 호출되고, 그 결과를 리턴하는 보조적 역할
🔍 2 - 3 SQL 최적화 기본 원리
- 옵티마이저(Optimizer)
- 규칙 기반 옵티마이저 (RBO)
- 제일 낮은 우선순위 : 전체 테이블 스캔
- 제일 높은 우선순위 : ROWID(행에 대한 고유 주소)를 활용해 테이블 액세스
- 적절한 인덱스 존재하면 전체 테이블 스캔보다 인덱스를 사용
- 통계 정보가 변경되면 실행 계획이 달라질 수 있음
- 비용기반 옵티마이저 (CBO)
- SQL문을 실행하는데 소요될 처리시간 및 CPU, I/O 자원량 등을 계산해 가장 효율적일 것으로 예상되는 실행 계획을 선택
- 항상 인덱스 스캔이 유리한 것은 아님
- 규칙 기반 옵티마이저 (RBO)
- 실행 계획
- SQL 처리를 위한 실행 절차와 방법 표현, 예상 정보
- 구성 요소 : 조인 기법, 조인 연산 , 액세스 기법 , 최적화 정보
- 읽는 순서 : 위에서 아래로 , 안에서 밖으로
- SQL 처리 흐름도 : SQL 실행 계획을 시각화해서 표현, 성능적인 측면 표현, 실행 시간 알 수 없음
- 실행계획(실행방법)이 달라진다고 해서 결과는 달라지지 않고 성능은 달라질 수 있음
- JOIN 기법
- NL JOIN : OLTP의 목록 처리 업무에 많이 사용 (랜덤 액세스 방식)
- 조인 컬럼에 적당한 인덱스가 있어 자연 조인이 효율적일 때 유용
- Driving Table의 조인데이터 양이 큰 영향을 줌
- 유니크 인덱스를 활용해 수행시간이 적게 걸리는 소량 테이블을 온라인 조회하는 경우 유용
- 선택도가 낮은(결과 행 수가 적은) 테이블이 선행 테이블로 선택되는 것이 유리함
- HASH JOIN : 데이터 집계 업무에 많이 사용
- 조인 컬럼의 인덱스를 사용하지 않음
- Sort Merge Join 하기에 두 테이블이 너무 커서 소트 부하가 심할 때 유용
- 한쪽 테이블이 주 메모리의 가용 메모리에 담길 정도로 충분히 작고 해시 키 속성에 중복 값이 적을 때 효과적
- 행의 수가 작은 테이블을 선행 테이블로 선택하는 것이 유리함
- EQUI Join 조건에서만 동작 (동등 조인)
- SORT MERGE JOIN : 데이터 집계 업무에 많이 사용 (스캔 방식)
- 조인 조건의 인덱스 유무에 영향 X
- 조인 컬럼을 기준으로 데이터를 정렬하여 조인 수행
- NL JOIN에서 부담이 되던 넓은 범위의 데이터를 처리할 때 이용
- 정렬할 데이터가 많아 메모리에서 모든 정렬 작업을 수행하기 어려운 경우 임시 영역을 사용하기 때문에 성능 저하
- 대상 테이블이 Join Key 컬럼으로 정렬되어 있을 때 Hash Join보다 우수한 성능
- NL JOIN : OLTP의 목록 처리 업무에 많이 사용 (랜덤 액세스 방식)
- 인덱스
- 목적 : 조회 성능 최적화 (삽입, 삭제, 갱신의 경우 부하 가중)
- UPDATE : 인덱스를 구성하는 컬럼 이외의 데이터가 갱신될 때는 인덱스로 인한 부하 발생 X
- 인덱스 범위 스캔 : 결과 건수만크 반환(없으면 반환 X)
- 기본 인덱스 : UNIQUE & NOT NULL 제약조건
- 보조 인덱스 : UNIQUE가 아니면 중복 데이터 입력 가능, 자주 변경되는 속성은 성능에 안좋은 영향
- 인덱스가 존재하는 상황에서 데이터를 입력하면 매번 인덱스 정렬 발생 → 대량의 데이터 삽입 시 모든 인덱스 제거, 삽입이 끝나면 인덱스 재생성
- 랜덤 액세스 : 인덱스를 스캔하여 테이블로 데이터를 찾아가는 방식 (부하 큼) → 대량의 데이터를 읽는 경우 인덱스 스캔보다 테이블 전체 스캔이 유리할 수 있음
- 테이블의 전체 테이블을 읽는 경우 인덱스를 사용하지 않는 FTS 사용
- 목적 : 조회 성능 최적화 (삽입, 삭제, 갱신의 경우 부하 가중)
- 인덱스의 종류
- B 트리 인덱스
- 브랜치 블록(분기 목적)과 리프 블록(인덱스 구성하는 컬럼 값으로 정렬)으로 구성
- 관계형 데이터베이스 , OLTP 환경에서 가장 많이 사용
- 테이블 내 데이터 중 10% 이하의 데이터를 검색할 때 유리
- 일치 및 범위 검색에 적절한 구조
- BITMAP 인덱스
- 시스템에서 사용될 질의를 시스템 구현 시에 모두 알 수 없는 경우인 DW 및 AD-HOC 질의 환경을 위해 설계
- 하나의 인덱스 키 엔트리가 많은 행에 대한 포인터 저장
- CLUSTERED 인덱스
- 인덱스의 리프 페이지가 곧 데이터 페이지
- 리프 페이지의 모든 데이터는 인덱스 키 컬럼 순으로 물리적으로 정렬되어 저장
- SQL Server의 클러스터형 인덱스는 ORACLE의 IOT와 매우 유사
- B 트리 인덱스