반정규화
- 데이터 조회시 디스크 입출력 양이 많아서 성능이 저하되거나 조인으로 인한 성능저하가 예상되는 경우 반정규화 수행
- 반정규화 수행 전, 통계/중복/이력/부분 테이블 추가를 통해 반정규화를 회피하려고 함
- 반정규화 검토 대상
- 한 테이블의 일정 범위만 자주 조회하는 경우
- 대량의 데이터가 있고 대량의 데이터 범위를 자주 처리하는 경우
- 통계성 정보를 자주 필요로 하는 경우 통계 테이블을 추가
- 테이블이 지나치게 많은 조인이 필요한 경우
데이터 성능
- 로우 체이닝 : 로우 길이가 너무 길어서 두 개 이상의 데이터 블록에 걸쳐서 하나의 로우가 저장되는 경우
- 로우 마이그레이션 : 데이터 블록에서 수정이 발생하면 수정된 데이터를 해당 데이터 블록에서 저장하지 못하고 다른 블록의 빈 공간을 찾아 저장하는 방식으로 디스크 입출력 부하가 커진다
SQL Server vs Oracle
SQL 기본
- 처음 테이블을 만들고 insert를 하다가 어떤 컬럼에 default 값을 지정하는 DDL을 수행한 경우, 해당 컬럼에 값을 지정하지 않고 insert를 하는 경우 default 값은 그 이후부터 적용됨. DEFAULT 소급 적용 X
- TCL : 에러 발생 후 커밋을 하면 이전 값이 그대로 보전되어야 함. 변경된 경우는 원자성 원칙에 위배된 것 ACID
- ** ACIDConsistency 일관성 : 트랜잭션 실행 전 후의 데이터 베이스에 잘못이 없어야 함Durability 지속성 : 트랜잭션 성공적 수행 시 갱신된 내용이 영구적으로 저장됨
- Isolation 고립성 : 트랜잭션 실행 도 중 다른 트랜잭션의 영향을 받지 않음
- Atomicity 원자성 : 트랜잭션에서 정의된 연산들은 모두 성공하거나 모두 실행되지 않은 둘 중 하나의 상태
- 같은 이름의 save 포인트를 지정했을 경우, 가장 아래쪽에, 최신에 정의된 save point가 유효함
- 문자열 비교 연산
- CHAR : 길이가 다른 경우 짧은 쪽에 스페이스를 추가해서 길이를 같게 만든 후 → 서로 다른 문자가 나올 때까지 비교
- VARCHAR : 서로 다른 문자가 나올 때까지 비교 → 끝까지 같다면 길이가 더 긴 것이 크다고 판단
- 비교 연산자를 조건절에 사용할 때 해당 컬럼에 null인 값이 포함되어 있는 경우, NVL()로 null 값을 처리해야 판단할 수 있음. null은 어떤 비교를 해도 null이 나오기 때문
- NULL은 비교 대상이 안되기 때문에 in(A,B,...,NULL)을 사용해도 NULL인 값을 가져오지 않음 , 즉 비교연산자에 사용된 NULL은 무용지물
- 뒤 또는 앞 등 불필요한 공백이 저장된 데이터를 비교할 때는 TRIM 함수를 사용 LTRIM은 앞 공백, RTRIM은 뒤 공백을 제거
- 집계 함수
- AVG, SUM 등은 NULL이 포함된 경우 무시하고 계산
- COUNT(*) 은 NULL을 0으로
- 순위 함수
- DENSE_RANK : 1,2,2,3,3,4, ...
- RANK: 1,2,2,4,...
- FROM 절에 ALIAS 사용을 위해 AS 키워드 사용하지 않음
- NVL(COL, B) : COL 에 값이 NULL 이면 B 반환 / NULL 인 값을 처리하기 위한 함수
- dirty read: 아직 커밋되지 않은 값이 읽힌 것
- non repeatable read : 동일한 트랜잭션 수행했는데 그 결과가 다른 경우 (phantom read 도 비슷 , 없던 데이터가 읽히는 것)
- 1/24/60 = 1분 , 1/24 = 1시간
- 숫자/0 = 에러 / 0/숫자 = 0
- 연산에 null이 포함되면 항상 Null
- GROUP BY 하면 ORDER BY 절에 집계 함수 사용 가능
SQL 활용
JOIN
- NATURAL JOIN에 사용된 열을 식별자를 가질 수 없음
- 두 테이블에 데이터타입과 이름이 동일한 컬럼이 하나 반드시 존재해야 가능
- 그래서 조인컬럼을 명시하지 않아도 됨
- 예를 들어, col1이 두 테이블에 공통으로 존재하여 조인 조건으로 사용된 상태에서 tab1.col1을 select 절에 사용하면 안됨
- CROSS JOIN 결과 건수
- tab 1에 row 개수 X tab2에 row 개수
- 조인 조건이 없는 경우 발생
- NON equi join : 조인 조건을 제외한 cross 조인을 한 후, where 절로 필터 처리 후 select
- n개의 테이블을 조인하면 최소 n-1번의 조인이 필요함
CUBE, ROLLUP, GROUPING SET 비교
- GROUPING SETS(A,B,C)
- = GROUP BY A UNION ALL GROUP BY B UNION ALL GROUP BY C
- 각 인자 컬럼을 기준으로 그룹핑한 결과를 중복 제거 없이 합친 결과
- 인자의 순서는 무관!
- ROLLUP
- 그룹핑 컬럼이 N 개 생기면 N+1 level의 subtotal이 생김
- 예를 들어 2개의 컬럼으로 그룹핑한 경우 3개의 소계 행이 생겨야 함
- 인자의 순서가 바뀌면 그 결과도 바뀜
- GROUP BY A, B 하면 A와 B 컬럼의 값으로 조합을 만들어 그 조합들이 행으로 오는 것
- 자동 정렬
- GROUP BY 해서 나온 그룹 마다 소계를 추가하고, 마지막 1건의 total 을 추가
- CUBE
- ROLLUP과 달리 인자 순서와 상관없이 모든 경우의 조합을 만듦
- 자동 정렬 안해줌
- 모든 경우의 소계 행을 추가
- N 개의 그룹이 만들어진다면 2^N개의 소계가 만들어짐
- CUBE(A,B) 면 A로 그룹한 결과의 소계 + B로 그룹한 결과의 소계 + A,B로 그룹한 결과의 소계
PARTITION
- 위→ 아래 누적 값 : RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
- PERCENT_RANK : 파티션 하나를 100이라 치고 파티션 내 행의 순서별 백분율을 구하는 함수
- CUME_DIST
- NTILE
- RATIO_TO_REPORT = 해당 값/ 전체 값
- MOD(M,N) : M을 N으로 나누었을 때의 나머지
- OVER() = default, 전체 테이블이 하나의 파티션이라고 가정하는 디폴트 !
계층형 테이블
- 계층형 질의에서 ROOT LEVEL = 1
- connect by에서 prior 키워드가 바로 앞에 붙은 쪽이 자식이 되는것connect by A = prior B 하면 A → B로 역방향
- connet by prior A = B 하면 B가 부모 → A 가 자식으로 순방향
서브쿼리
- 단일행 : 단일행비교연산자 사용해서 실행 결과 1 건 반환
- 다중행 : 다중행비교연산자 사용해서 실행결과 여러개 반환
- 다중컬럼 : 결과가 부분 테이블 형태로 나옴, 이걸 조건절에서 받아쓰려면 일치하는 컬럼으로 받아줘야함
- ex) WHERE (A,B) IN (SELECT C1,C2 FROM TAB2 WHERE C2=1;) 이렇게 서브쿼리에서 도출된 테이블의 각 c1,c2 행이 a,b에 대응되어야 함
- 스칼라 = 결과 하나 반환
TRIGGER
- :OLD = 수행 전 데이터, :NEW = 수행 후 데이터
- 특정 체이블에 DML 문이 수행되었을 때 자동으로 동작하도록 작성된 프로그램
값 치환 함수
- COALESCE(a, b, c, ...) : 컬럼 a를 확인 했을 때 값이 null 이면 같은 행의 컬럼 b 값을 확인하고... 를 반복해서 null이 아닌 값을 찾고 인자로 온 모든 컬럼의 값이 null 이면 null을 출력하거나 마지막에 default 표현식을 출력
- NULLIF(A,B) : A가 null이면 B 출력 == NVL(A,B)
- ISNULL(A,B) : A==B 면 NULL 출력
- MIN, MAX 를 데이터 없는 테이블에 적용하면 NULL 반환
- AVG, SUM은 null 값을 제외하고 계산
- DECODE(COL, A, a, B, b, ...)
- COL 컬럼의 값이. A 이면 a 를 출력, B 면 b 출력 / 그래서 이 함수의 인자 개수는 반드시 홀수여야 함
- ABS(A): A 의 절댓값
CONSTRAINTS
- DELETE, UPDATE CONSTRAINT
- cascade : 부모 삭제 → 자식 삭제
- set null : 부모 삭제 → 자식의 부모 컬럼 값 Null
- set default : 부모 삭제 → 자식의 부모 컬럼 값 default 값으로
- restrict : 자식이 참조하고 있는 부모 삭제 불가
- INSERT CONTRAINT
- automatic : 부모가 없는 경우 자식이 입력하면 부모 값 만들어서 참조
- set null
- set default
- dependent : 부모가 있는 경우에만 자식이 참조 가능
기타
- 권한 집합 = ROLE
- VIEW의 특징
- 독립성 : 테이블 구조 변경이 응용프로그램에 영향 미치지 않음
- 편리성 : 복잡한 질의를 뷰로 미리 생성해 두어 관련 질의를 단순하게 할 수 있음
- 보안성
- 실제 데이터를 가지고 있지 않음 (물리적 저장 X)
- 기본 연산자를 사용하면 성능이 저하됨
- ALL : 정렬하지 않고, 중복 제거하지 않고 출력
- DISTICT : 중복을 제거하고 출력
- NOT IN(inline view).IN을 하면 모든 건수가 출력됨
- inline view에 null 이 포함되면 null로 인해 모든 조건이 참이 됨 → 0 건 출력
- NOT EXISTS ⇒ OUTER JOIN + 조인 조건이 된 컬럼의 is null 체크 (WHERE 기준이 아닌 테이블의 조인 컬럼 IS NULL)
- ANY == NOT EXISTS IN
- WHERE EXIST ( ... = null) ⇒ 아무것도 만족할 수 없어서 0건의 결과를 출력
- MERGEWHEN MATCHED THEN // 병합 조건과 일치할 때 아래 DML 수행DELETE WHERE ... // 위 DML을 수행한 행에 대한 것들만 다음 DML을 수행할 수 있음INSERT VALUES ...
- WHENE NOT MATCHED THEN // 병합 조건과 일치하지 않을 때 수행
- UPDATE SET ..
- MERGE INTO TABLE1 USING TABLE2 ON (병합 조건절) // TABLE1을 기준으로 병합
- TRUNCATE, DROP : 로그 남지 않아서 rollback 불가능
옵티마이저
실행 계획 순서
- 선행 테이블 full access
- 인덱스 스캔
- 인덱스에서 찾은 row id 로 테이블 access
- join
- 후행 테이블에 대해서 1-3 과정 반복
- join은 아래에서 위 순서로 실행
- 마지막 select
JOIN 종류
- HASH JOIN
- 인덱스 없어도 됨
- 대용량 데이터에 사용
- EQUI 조인에서만 사용 가능 → 비동등 조인인 경우 SM JOIN
- 데이터 집계용
- SORT MERGE JOIN
- 대량 데이터 정렬 후 조인
- 동등, 비동등 조인 모두 사용 가능
- 데이터 집계용
- 인덱스 유무 영향 없음
- NESTED LOOP JOIN
- OLTP 온라인 소량 조회에 많이 사용됨
- 조인컬럼에 적당한 인덱스가 있는 경우 → 없는 경우 Hash join
- 자연조인이 효율적일 때 유리한 방식
- 선행 테이블이 작을수록 유리함
- 선행 테이블이 너무 크면 랜덤 액세스 부하가 너무 큼 → 이 때 hash join을 해라!
인덱스 스캔 방식
- index unique scan
- not null, uniqe key 필요, 인덱스 구성 컬럼을 조건절에서 모두 동등 조건을 걸어줘야 함
- 예를들어 인덱스가 col1, col2로 구성되어 있다면 where col1=n and col2=m 이렇게
- index range scan
- between like < > 등 범위로 조건 비교
- index skip scan
- 선행 컬럼에 대한 조건 없이 후행 컬럼에 대한 조건만 있는 경우
- index full scan
- 조건절에서 인덱스 컬럼 중 하나 이상을 사용하거나 사용한 컬럼이 모두 하나의 인덱스에 존재하는 경우 하나의 인덱스를 풀 스캔!
- 인덱스 컬럼 중 하나는 반드시 not null 이어야 함
- 벙렬 처리 못함
- index fast full scan
- index full scan과 동일한데 인덱스에서 row id를 찾아 테이블에 접근하는게 아니라 그 값 자체를 인덱스에 별도의 컬럼을 추가해서 가지고 있음
- 병렬 처리가 가능
- 정렬하지 않음
- 비트맵 인덱스는 이 방식이 불가능함
인덱스 종류
- B 트리 인덱스
- 키 값 + row id
- 브랜치 (분기용) + 리프 (인덱스를 구성하는 컬럼 값)
- 행단위 lock 지원
- 차수가 높은 (=행, 데이터가 여러개인) 컬럼에 적용
- null 비교 부정형 비교 X
- RDB의 주요 인덱스로 가장 많이 사용됨
- OLTP 시스템 환경에서 많이 사용됨
- 대용량 테이블 탐색에 불리함
- 일치 및 범위 검색에 유리
- 비트맵 인덱스
- 대용량 데이터 처리에 용이
- key + start row id + end row id + bitmap
- 행 단위 lock 지원 X
- null 비교 부정형 비교 O
- DW AD-HOC 질의 환경을 위해 설계됨
- 하나의 인덱스 키가 여러개의 포인터 행을 저장
- 클러스터드 인덱스
- 리프페이지 = 데이터 페이지
- 인덱스 키 컬럼 순으로 물리적 정렬되어 있음
- 인덱스 구성 컬럼이 아닌 데이터를 업데이트 할 때 index update 부하 없음
실행 계획
- 액세스 기법, 예상비용, 조인 순서
- 위→ 아래, 안 → 밖 순서로 읽기
- 실행계획을 시각화한 것 = SQL 처리 흐름도
'컴퓨터 공학 > 데이터베이스' 카테고리의 다른 글
SQLD) 데이터베이스 구조와 성능 (0) | 2022.01.07 |
---|---|
반정규화 De-normalization (0) | 2022.01.07 |
정규화 Normalization (0) | 2022.01.07 |
ERD (Entity Relationship Diagram) 기초 (0) | 2022.01.07 |
데이터 모델링의 이해 (0) | 2022.01.07 |