# 4. 자격증/SQLD

SQLD 자격증 # 데이터 모델과 성능(과목1)_정규화와 성능

둥굴둥굴둥굴레차 2021. 11. 11. 20:15
정규화, 비정규화

 

1. 정규화를 통한 성능 향상 전략

정규화란

기본적으로 데이터에 대한 중복성을 제거하여 주고 성능이 향상되는 특징을 가지고 있다.

 

데이터베이스에서 데이터를 처리할 때 성능이라고 하면 조회 성능입력/수정/삭제 성능의 두 부류로 구분된다

이 두 가지 성능이 모두 우수하면 좋겠지만 데이터 모델을 구성하는 방식에 따라 두 성능이 Trade-Off 되어 나타나는 경우가 많이 있다.
 

정규화를 수행한다는 것은 데이터를 결정하는 결정자에 의해 함수적 종속을 가지고 있는 일반 속성을 의존자로 하여 입력/수정/삭제 이상을 제거하는 것이다. 데이터의 중복속성을 제거하고 결정자에 의해 동일한 의미의 일반 속성이 하나의 테이블로 집약되므로 한 테이블의 데이터 용량이 최소화되는 효과가 있다따라서 정규화된 테이블은 데이터를 처리할 때 속도가 빨라질 수도 있고 느려질 수도 있는 특성이 있다.

그림 -2-3을 보면 정규화 수행 모델은 데이터를 입력/수정/삭제할 때 일반적으로 반정규화된 테이블에 비해 처리 성능이 향상된다단 데이터를 조회할 때에는 처리 조건에 따라 조회 성능이 향상될 수도 있고 저하될 수도 있다.

 

 

2. 반정규화된 테이블의 성능 저하 사례 1

정규화하여 조인이 발생하면 성능이 심각하게 저하되는가

사실 조인 성능 저하는 아주 미미하게 발생된다.

그림 -2-4의 왼쪽 그림은 2차 정규화가 안 된 반정규화된 테이블의 모습이고 오른쪽 그림은 부분 키 종속을 정규화하여 두 개의 테이블로 분리해 2차 정규화된 테이블의 모습이다.

 

2차 정규화가 안 된 테이블은 직급명과 함께 반정규화된 관서 번호, 관서명을 조회하면 하나의 테이블에서 데이터가 조회가 된다. 2차 정규화된 테이블은 관서 번호, 관서명이 관서 테이블에만 존재하기 때문에 두 개의 테이블을 조인하여 처리해야 한다.


정부 보관금 관서 원장에서 데이터를 조회하는 것이나관서(A)와 정부 보관금 관서 원장(B)을(B) 조인하여 데이터를 조회하나 처리 성능은 사용자가 느끼기에는 거의 차이가 나지 않는다. PK가 걸려있는 방향으로 조인이 걸려 Unique Index를 곧바로 찾아서 데이터를 조회하기 때문에하나의 테이블에서 조회하는 작업과 비교했을 때 미미하게 성능 차이가 날 뿐 사용자에게 크게 영향을 줄 만큼 성능이 저하되는 일은 없는 것이다.


게다가 위의 예를 ‘‘관서 등록일자가 2010년 이후 관서를 모두 조회하라는 SQL 구문을 처리하는 것으로 바꾸면, 2차 정규화된 테이블이 훨씬 빠르다.

 

그림 -2-5에서와 같이 왼쪽 테이블에서는 불필요하게 납부자 번호만큼 누적된 데이터를 읽어서 결과를 구분하여 보여주어야 하지만 오른쪽은 관서수만큼만 존재하는 데이터를 읽어 곧바로 결과를 보여주기 때문이다이렇게 단순한 예만 보아도 정규화를 수행하면 무조건 조회 성능이 저하된다는 고정관념이 틀렸다는 것을 알 수 있다.

3. 반정규화된 테이블의 성능 저하 사례 2

이 업무에서는 어떤 물건을 매각할 때 매각일자를 정하고 그 일자에 해당하는 매각시간매각 시간과 매각 장소 매각 장소가 결정하는 속성의 성격을 가지고 있다. 즉. 매각일자가 결정자가 되고 매각 시간과 매각 장소가 의존자가 되는 함수적 종속관계가 형성되는 관계이다. 매각일자는 5천 건이 있고 일자별 매각물건은 100만 건이 있는 것으로 가정하자.

예를 들어 그림 -2-6의 모델에서 서울 7에서 매각된 총 매각금액, 총 유찰 금액을 산출하는 조회용 SQLSQL 문장을 작성하면 다음과 같다.

SELECT B. 총 매각금액 , B. 총 유찰 금액
FROM (SELECT DISTINCT 매각일자
          FROM 일자별 매각물건
         WHERE 매각 장소 = '서울 7호') A <== 100만 건의 데이터를 읽어 DISTINCT 함
, 매각일자별 매각 내역 B
 WHERE A. 매각일자 = B. 매각일자
   AND A. 매각 장소 = B. 매각 장소;

대량의 데이터에서 조인 조건이 되는 대상을 찾기 위해 인라인 뷰를 사용하기 때문에 성능이 저하된다

 

이를 정규화하려면 복합 식별자 중에서 일반 속성이 주식 별자 속성 중 일부에만 종속관계를 가지고 있으므로 2차 정규화의 대상이 된다. 2차 정규화를 적용하면 그림 -2-7과 같은 모델이 된다.

 

2차 정규화를 적용하여 매각일자를 PK로 하고 매각시간매각 시간과 매각 장소 매각 장소는 일반 속성이 되었다.

 

정규화를 적용했기 때문에 매각일자를 PK로 사용하는 매각일자별 매각 내역과도 관계가 연결된다. 따라서 업무 흐름에 따른 정확한 데이터 모델링 표기도 가능해지고드라이빙이 된 테이블 이 5천 건의 매각기일 테이블이 되므로 성능도 향상된다.

 

만약 위의 모델에서 서울 7에서 매각된 총 매각금액, 총 유찰 금액을 산출하는 조회용 SQLSQL 문장을 작성하면 다음과 같이 나온다.

SELECT B. 총 매각금액 , B. 총 유찰 금액
FROM 매각기일 A, 매각일자별 매각 내역 B
 WHERE A. 매각 장소 = '서울 7호' <== 5천 건의 데이터를 읽음
   AND A. 매각일자 = B. 매각일자
   AND A. 매각 장소 = B. 매각 장소;

매각기일 테이블이 정규화되면서 드라이빙이 되는 대상 테이블의 데이터가 5천 건으로 줄어들어 조회 처리가 빨라진다.

 

 

4. 반정규화된 테이블의 성능 저하 사례 3

다음 사례는 동일한 속성 형식을 두 개 이상의 속성으로 나열하여 반정규화한 경우에 해당한다계층형 데이터베이스를 많이 사용했던 과거 데이터 모델링의 습관이 남아서인지 관계형 데이터베이스에서도 동일한 속성을 한 테이블에 속성 1, 속성속성 2, 속성 속성 3 데이터 모델링을 하는 경우가 많이 있다.


그림 -2-8
을 보면모델이라고 하는 테이블에 업무적으로 필요한 8개의 인덱스가 이미 생성되어 있다데이터는 30만 건이고 온라인 환경의 데이터베이스라고 가정하자유형 기능분류코드에 따라 데이터를 조회하는 경우가 많이 나타나 인덱스를 생성하려면 유형 기능분류코드 각각에 대해 인덱스를 생성해야 하므로 9개나 되는 인덱스를 추가 생성해야 한다.


 

참고로한 테이블에 인덱스가 많아지면 조회 성능은 향상되지만 데이터 입력/수정/삭제 성능은 저하된다그래서 일반 업무처리(온라인 성( 업무)에서는 인덱스 수를 가급적 7~8개가 넘지 않도록 하는 것이 좋다

 

그런데 그림 -2-8의 모델은 다른 필요한 인덱스 이외에 유형 기능분류코드 속성에 해당하는 인덱스를 9개나 추가적으로 생성해야 하므로 실전 프로젝트에서는 어쩔 수 없이 인덱스를 생성하지 않거나 A유형 기능분류코드 1 하나만 인덱스를 생성하는 경우가 생긴다이에 따라 A유형 기능분류코드 1, A유형 기능분류코드 2,유형기능분류코드 A유형 기능분류코드 3... 을 이용하면 SQL의 성능이 저하되는 경우가 많다.


만약 각 유형 코드별로 조건을 부여하여 모델 코드와 모델명을 조회하는 SQLSQL 문장을 작성한다면 다음과 같이 나온다.

SELECT 모델 코드,
       모델명
  FROM 모델
 WHERE ( A유형 기능분류코드 1 = '01' )
    OR ( B유형 기능분류코드 2 = '02' )
    OR ( C유형 기능분류코드 3 = '07' )
    OR ( D유형 기능분류코드 4 = '01' )
    OR ( E유형 기능분류코드 5 = '02' )
    OR ( F유형 기능분류코드 6 = '07' )
    OR ( G유형 기능분류코드 7 = '03' )
    OR ( H유형 기능분류코드 8 = '09' )
    OR ( I유형 기능분류코드 9 = '09' );

 

각 유형별로 모두 인덱스가 걸려 있어야 인덱스에 의해 데이터를 찾을 수 있다이런 모델은 다음과 같이 정규화를 적용해야 한다.


중복 속성에 대한 분리가 1차 정규화의 정의임을 고려하면 모델 테이블은 1차 정규화의 대상이 된다. 로우 단위의 대상도 1차 정규화의 대상이 되지만 칼럼 단위로 중복이 되는 경우도 1차 정규화의 대상이 된다. 따라서 모델에 대해 1차 정규화를 적용하면 그림 -2-9와 같이 분리될 수 있다.

 

하나의 테이블에 9개가 반복적으로 나열이 되어 있을 때는 인덱스 생성이 어려웠지만 정규화되어 분리된 이후에는 인덱스 추가 생성이 0개가 되었다또한 분리된 테이블 모델 기능분류코드에서 PK인덱스를 생성하여 이용함으로써 성능이 향상될 수 있다.

 

 

만약 각 유형 코드별로 조건을 부여하여 모델 코드와 모델명을 조회하는 SQLSQL 문장을 작성한다면 다음과 같이 작성된다.

SELECT A. 모델 코드, A. 모델명
 FROM 모델 A, 모델 기능분류코드 B
 WHERE ( B. 유형 코드 = 'A'
           AND B. 기능분류코드 = '01'
           AND A. 모델 코드 = B. 모델 코드 )
    OR ( B. 유형 코드 = 'B'
           AND B. 기능분류코드 = '02'
           AND A. 모델 코드 = B. 모델 코드 )
    OR ( B. 유형 코드 = 'C'
           AND B. 기능분류코드 = '07'
           AND A. 모델 코드 = B. 모델 코드 )
    OR ( B. 유형 코드 = 'D'
           AND B. 기능분류코드 = '01'
           AND A. 모델 코드 = B. 모델 코드 )
    OR ( B. 유형 코드 = 'E'
           AND B. 기능분류코드 = '02'
           AND A. 모델 코드 = B. 모델 코드 )
    OR ( B. 유형 코드 = 'F'
           AND B. 기능분류코드 = '07'
           AND A. 모델 코드 = B. 모델 코드 )
    OR ( B. 유형 코드 = 'G'
           AND B. 기능분류코드 = '03'
           AND A. 모델 코드 = B. 모델 코드 )
    OR ( B. 유형 코드 = 'H'
           AND B. 기능분류코드 = '09'
           AND A. 모델 코드 = B. 모델 코드 )
    OR ( B. 유형 코드 = 'I'
           AND B. 기능분류코드 = '09'
           AND A. 모델 코드 = B. 모델 코드 ) ;

 

위 SQLSQL 구문은 유형 코드+기능분류코드+모델 코드에 인덱스가 걸려 있으므로 인덱스를 통해 데이터를 조회함으로써 성능이 향상된다.


실전 프로젝트에서도 많은 데이터 모델이 칼럼 단위에서 중복된 경우가 발견된다이에 대한 파급효과 계산 없이 무조건 칼럼 단위로 COL1, COL2, COL3... 이런 식으로 데이터 모델링을 하는 것은 근본적으로 SQLSQL 문장의 성능을 나쁘게 하는 결과를 초래할 수도 있으므로 인덱스 생성 영향도를 파악한 이후에 적용하는 것이 좋은 방법이 된다

 

 

5. 반정규화된 테이블의 성능 저하 사례 4

그림 -2-10과 같은 경우도 동일한 사례이다.

일재고와 일재고 상세를 구분함으로써 일 재고에 발생되는 트랜잭션의 성능 저하를 예방할 수 있게 되었다


✅ REFERENCE

 

제 2절 정규화와 성능

1. 정규화를 통한 성능 향상 전략 정규화란? 다양한 유형의 검사를 통해 데이터 모델을 좀더 구조화하고 개...

blog.naver.com