728x90
반응형

SQL처음 공부할 때는 알았으려나...?

그동안 실무를 하면서 너무 UNION ALL 에 익숙해져서 둘의 차이를 잊고 있었다!

  UNION UNION ALL
중복 처리 중복 Row 제외 중복 Row 포함

 

UNION (= UNION DISTINCT)

(SELECT cust_no, lst_lgin_dtm FROM A) 

UNION 

(SELECT cust_no, lst_lgin_dtm FROM B)
CUST_NO    LST_LGIN_DTM
-------------------------------
1111       2022/10/31 10:21:59
1111	   2022/11/21 17:49:34
1111	   2023/04/02 23:51:01
1111	   2023/04/04 09:51:01

두 테이블에서 같은 데이터 row가 2건 이상 나오면 해당 데이터는 1건만 남기고 나머지는 지운다.

 

UNION ALL

(SELECT cust_no, lst_lgin_dtm FROM A) 

UNION ALL

(SELECT cust_no, lst_lgin_dtm FROM B)
CUST_NO    LST_LGIN_DTM
-------------------------------
1111       2022/10/31 10:21:59
1111	   2022/11/21 17:49:34
1111	   2023/04/02 23:51:01
1111	   2023/04/02 23:51:01
1111	   2023/04/02 23:51:01
1111	   2023/04/04 09:51:01

두 테이블에서 같은 데이터 row가 2건 이상 나오면 한 건도 빠짐없이 모두 조회된다.

728x90
반응형
728x90
반응형

안녕하세요! 오늘은 파티션(Partition)에 대해서 알아보겠습니다. 

 

파티션 테이블이란?

파티션 테이블(Partition Table)이란 사용자가 정의한 기준에 따라 데이터를 분할하여 저장해놓은 테이블입니다. 논리적인 1개의 테이블에 대해서, 여러개의 파티션 테이블을 분할하여 물리적으로 다른 공간에 저장하는 것이죠!

 

이때, 실제 데이터가 물리적으로 저장되는 곳은 Partition으로 나누어진 Tablespace입니다. 즉, 파티션되지 않은 테이블은 테이블과 저장영역이 1:1 관계지만, 파티션된 테이블일 때는 1:M 관계가 됩니다.

 

 

파티션 테이블을 사용하는 이유는?

일반적으로는 오랜 기간 동안 쌓인 데이터를 효율적으로 관리하고 성능저하를 방지하기 위한 용도로 파티션 테이블을 사용합니다. 서로 다른 파티션에 데이터를 저장함으로써 물리적 공간이 분할되어 노드 간의 디스크 경합을 최소화할 수 있다는 장점이 있어 많이 사용합니다!

 

또한 인덱스를 이용한 Random 액세스 방식은 데이터의 양이 일정 수준을 넘어가는 순간 Full Table Scan보다 오히려 성능이 나빠진다고 합니다. 그렇다고 대용량 데이터 테이블을 Full Scan 하는 것은 매우 비효율적이기 때문에, 테이블을 파티션 단위로 나누어 Full Table Scan이라 하더라도 일부 세그먼트만 읽고 작업을 마칠 수 있게 합니다.

 

 

실무 사례 : 최종 로그인 기록 조회 시간 단축

최근 고객의 로그인 실적에 따라 금리 우대를 제공하는 상품이 개발되었습니다. 그래서 고객의 월별 최종로그인 일자를 수신팀에 제공해야 하는 일이 생겼습니다. 

 

하지만 고객의 최종 로그인 정보가 기록되어 있는 테이블의 데이터가 너무 방대했습니다. 로그인 기록 뿐 아니라 기타 하나원큐 고객들의 모든 활동 내역이 저장되어 있었기 때문에, 최종 로그인 기록을 SELECT하는 과정에서 많은 시간이 소요되었습니다.

 

이를 개선하기 위해 해당 테이블 개요를 살펴보니 테이블 날짜에 따라 분기별로 Range Partition이 생성되어 있는 것을 알 수 있었습니다. 기존 쿼리의 실행계획을 살펴보니 Full Table Scan이 이루어 지고 있었기 때문에 WHERE조건 내에 Range Partition Key로 잡힌 컬럼의 범위 조건을 추가하여 Partition Range로 조회 범위를 줄여 SQL 실행 시간을 단축시켰습니다.   

 

 

파티션의 종류는?

① RANGE : 범위 기준으로 분할
② LIST : 특정 값들의 집합으로 분할
③ HASH
④ INTERVAL
⑤ REFERENCE

 

RANGE

- 날짜나 숫자 처럼 범위를 가진 데이터(연속된 값)를 기준으로 하여 만든 파티션 테이블입니다.

- 함께 저장되어야 할 데이터의 범위를 지정하여 테이블을 파티션 합니다.

- Column Value의 범위를 기준으로 하여 행을 분할하는 형태입니다.

SQL> CREATE TABLE range_partition
( 
	range_key_column  date NOT NULL,
  	data              varchar2(20)
)
PARTITION BY RANGE ( range_key_column )
(
	PARTITION part_1 VALUES LESS THAN ( to_date('01/01/2022','dd/mm/yyyy')),
   	PARTITION part_2 VALUES LESS THAN ( to_date('01/01/2023','dd/mm/yyyy'))
)


Table created.

 

 

LIST

- 특정값을 가진 데이터로 만든 파티션 테이블입니다.

- 데이터가 균등하게 분포되어 있어 데이터 분포도가 낮지 않을때 유용합니다.

- 이산 값들을 집합으로 묶어 함께 저장될 데이터를 결정하기 때문에 다중 컬럼을 지원하지 않고 단일 컬럼만 가능합니다.

create table list_partition
(  
	state_cd varchar2(2),
    data varchar2(20)
)
partition by list(state_cd)
(
	partition part_1 values ( 'ME', 'NH', 'VT', 'MA' ),
    partition part_2 values ( 'CT', 'RI' , 'NY' )
) ;

 

 

HASH

- 해시 함수에 의해 자동으로 파티셔닝 되는 테이블입니다.

- 해시 파티션은 데이터가 어느 파티션에 지정될지 알 수 없기 때문에 관리의 목적보다는, 데이터를 분산시켜 디스크 성능을 개선하는데 목적을 두고 있습니다.

 

 

INTERVAL

 - Range 파티션과 유사하며 파티션이 추가되는 기준(규칙)을 지정할 때 사용합니다.
 - 기존 파티션에 데이터가 있고 새로운 데이터가 입력될 때에만 새로운 파티션을 생성합니다.
 - Range 파티션에서 MAXVALUE 파티션 지정 없이 생성한 경우, 후에 데이터가 추가됐을 때 지정한 INTERVAL 만큼의 범위를 가지는 파티션이 생성됩니다.

 

 

REFERENCE

 - 자식 테이블 파티션이 부모 테이블 파티션과 일대일 관계인 환경에서 자식 테이블을 파티션할 때 사용합니다.
 - 자식 테이블의 파티셔닝을 부모 테이블로부터 상속받습니다.
 - 파티셔닝 키는 자식 테이블의 실제 컬럼에 저장되지 않습니다.

 

 

여기까지 파티션 테이블에 대해서 알아보았습니다! 

728x90
반응형
728x90
반응형

인덱스가 걸려 있는 테이블에 DML을 하면 무조건 성능저하를 가져올까?

결론부터 말씀드리면 아닙니다! DML처리를 하려는 컬럼이 INDEX 컬럼이냐 아니냐에 따라 성능차이가 달라집니다. 

또한 DML 처리건수가 많지 않을 때에는 사용자가 느끼지 못할만큼 성능 저하에 끼치는 영향이 아주 미미하다고 합니다.

 

 

그럼 왜 테이블에 INSERT가 잦으면 인덱스 성능이 저한된다고 하는 걸까요?

테이블은 힙구조인데 반해, 인덱스는 클러스터형이기 때문입니다. 

- 테이블 : 정렬이 안된 힙구조의 데이터 집합
- 인덱스 : 클러스터링된 열을 사용하여 사용자 정의 열 정렬 순서가 있는 데이터 집합

아래 그림을 보시면 이해가 쉬울 것 같습니다! 일반 테이블과 인덱스 테이블의 차이가 보이시나요?

가장 왼쪽의 테이블이 바로 클러스터링 되지 않은 기본 테이블입니다. 내용을 보시면 데이터들이 뒤죽박죽 입력한 순서대로 정렬되어 있는 것을 알 수 있습니다. 이때 INSERT 하게 되면 남은 빈공간에 순서 상관없이 데이터를 추가만 하면 되기 때문에 성능저하와 관련이 없습니다.

 

반면, 오른쪽 두 개의 Clustered 테이블을 보시면 예쁘게 정렬되어 있는 것을 볼 수 있습니다. 이게 바로 인덱스 테이블 구조라고 보시면 됩니다. 이때, 새로운 데이터를 INSERT하게 되면, 정렬 순서에 맞는 빈 공간을 찾아 추가해야 하기 때문에 성능의 저하를 가져올 수 밖에 없습니다.

 

심지어 데이터를 추가할 빈 공간이 없다면? 기존 블록의 내용 중 일부를 새 블록에 기록한 후 기존 블록에 빈 공간을 만들어서 새로운 데이터를 추가해야하는 INDEX Split 현상이 발생하기 때문에 속도가 느려질 수 밖에 없게 됩니다.

 

 

DELETE와 UPDATE도 똑같은 이유로 인덱스의 성능저하를 가져올까요?

아닙니다. 우선 DELETE부터 설명해드리자면, 테이블에 DELETE가 발생해도 인덱스는 삭제되지 않습니다. 즉, 테이블 데이터는 삭제되어도 인덱스 테이블에는 그 내용이 그대로 남게 되는 거죠. 그래서 테이블 데이터는 1만건밖에 없어도, 인덱스 테이블에는 10만건의 데이터가 남아있을 수 있기 때문에 성능 저하는 가져온다고 말하는 것입니다. 

 

UDPATE의 경우는 어떨까요? 사실 인덱스에는 UDPATE의 개념이 없습니다. 그래서 만약 테이블에 UPDATE가 발생한다면, 인덱스에서는 [DELETE → INSERT] 즉, 두 번의 DML이 이루어지게 됩니다. 그래서 UDPATE는 INSERT, DELETE보다 2배의 작업이 수행되기 때문에 가장 부하가 크다고 볼 수 있습니다. 

 

 

 

그럼 DML이 자주 발생한 INDEX는 어떻게 관리해야 할까?

인덱스는 한번 만들어 놓는다고 해서 영구적으로 잘 사용할 수 있는 것이 아니라 데이터의 insert, delete, update 등을 통하여 성능이 저하되기 때문에, 인덱스를 지속적으로 사용하기 위해서는 꾸준한 관리가 필요하다고 합니다. 이를 바로 '인덱스 리빌드'라고 합니다. 저는 DBA가 아니기 때문에 해당 작업을 할 일은 없을 것 같아서 타 블로그 링크로 대체합니다! 자세한 내용이 궁금하신 분들은 아래 블로그를 참고해보세요^^~

 

※  인덱스 리빌드 참고 블로그 :

 

[Oracle] 인덱스 - 리빌드

뜻하지 않게 운영업무를 맡게되어 내 업무가 될지 몰랐던,, oracle 관리 작업을 시작하였다. 현재 엑사데이터에 여유공간이 전혀 없이 풀로 사용하고 있어 언제라도 장비가 꺼지면 데이터는 다 날

ssoondata.tistory.com

 

[오라클] 인덱스의 주의사항 및 관리방법(쿼리문 확인)

안녕하세요.앞서 인덱스의 개념과 종류에 대해 알아보았습니다.[개발/DB] - [오라클] 인덱스의 원리 및 개념과 종류(B-TREE, BITMAP INDEX) 오늘은 인덱스의 주의사항과 실습을 통하여 인덱스의 관리법

lee-mandu.tistory.com

 

 

728x90
반응형

+ Recent posts