DA 가이드

DA, SQL, DB보안 등 실무자를 위한 위한 DB기술 바이블!

애플리케이션 성능 개선

DB설계와 이용
데이터베이스 성능개선
애플리케이션 성능 개선
작성자
admin
작성일
2021-02-10 16:14
조회
2529

온라인 프로그램 성능 개선

온라인 프로그램의 성능 개선 목표는 응답 시간 단축인 경우가 대부분이다. 애플리케이션 사용자 가 업무를 수행하기 위해 최소한 응답 시간을 보장하고 더 나아가 효과적인 진행이 가능한 수준을 유 지해야 한다.

온라인 프로그램의 특징은 다음과 같다.


  • 화면 조회가 가능할 정도로 1회 조회 데이터가 소량이다.
  • 신속한 트랜잭션 처리가 요구된다.
  • 조회 조건이 단순하다.
  • 업무 형태에 따라 데이터 액세스 패턴이 고정되어 있다.
    온라인 프로그램 성능 개선 작업은 다음 사항을 고려한다.
  • 사용 빈도가 높은 SQL 문을 개선하는 것이 효과적이다.
  • 인덱스를 이용하여 데이터 액세스 범위를 줄이는 것이 효과적이다.
  • 부분 범위 처리로 응답 시간을 단축한다.
  • 부분 범위 처리를 하기 위해서 Nested-Loop 조인과 인덱스를 이용한 정렬을 유도한다.
  • 장기 트랜잭션 처리를 억제한다.

온라인 프로그램의 성능 개선 사례

상수 바인딩에 의해 발생되는 파싱 부하
문제점

최근 대중적인 개발 형태인 웹 기반의 애플리케이션은 SQL문 작성 시 조건절에 변수 바인딩을 실 행하는 정적인 형태의 작성 기법이 아니라 SQL문을 저장한 문자열에 사용자로부터 입력 받은 상 수 값을 직접 결합시켜 동적으로 실행시키는 상수 바인딩 형태의 작성 기법을 주로 사용한다. 이런 방법으로 개발된 시스템은 사용자가 작은 경우에는 문제가 되지 않으나 동시 접속자 수가 증가하 면 심각한 성능 저하 현상이 발생한다.


원인

이런 형태의 SQL 작성 기법은 개발이 용이하지만 데이터베이스에 과도한 파싱 부하 및 옵티마이 저 최적화 작업을 어렵게 만든다. 대부분의 데이터베이스들은 옵티마이저에 의해 실행 계획을 미 리 작성하여 정적으로 보관하고 있거나 동적으로 작성하여 작성된 정보를 담고 있는 파싱 정보를 데이터베이스의 공유 메모리 영역에 적재한다. 동일한 SQL문이 실행될 때 메모리에 적재된 실행 계획을 재사용한다. 상수가 바인딩되어 실행되는 SQL문은 상수 값의 변화에 따라 SQL문이 동적 으로 바뀌어 데이터베이스 메모리 영역에 보관되어 있는 실행 계획 정보를 재사용할 수 없거나 재 사용 확률이 상당히 낮아진다. 상수가 바인딩된 부분을 제외하고는 동일한 SQL문임에도 하드 파 싱을 해야 하는 일이 발생한다. 파싱에 소요되는 비용은 대부분 CPU 사용 시간이므로 SQL문 실 행 시 변수가 바인딩되어 파싱 결과를 재사용할 수 있도록 구현하는 것이 데이터베이스 성능을 안 정화시키는 데 유리하다.


웹 게시글 형태의 인터페이스 시 부분 범위 처리

인터넷이 대중화되면서 웹 서비스 아키텍처 구조가 보편화되었다. 웹아키텍처는 N-티어 구조로 실행 프로그램이 데이터베이스와 지속적인 세션을 가질 수 없다. 미들웨어를 사용하는 환경에서도 동일하다. 이런 환경에서는 클라이언트/서버의 2계층 구조에서 GUI 툴을 이용하여 쉽게 구현하던 부분 범위 처리에 의한 스크롤 처리가 불가능하다.

이러한 현실적인 어려움으로 인해 대부분의 게시판 인터페이스에서는 사용자 액션이 들어올 때마 다 해당 테이블 전체를 다시 읽거나 조건절에 만족하는 대상을 읽어 필요한 부분을 잘라 질의 결과를 반환하는 형태를 취한다. 이 방식은 대상 건수가 증가하면 할수록 응답 속도가 떨어질 수밖에 없으 며, 조회에서 조인을 하는 대상 테이블들의 조건이 어느 한 테이블에만 특정되는 것이 아니라 각각의 테이블에 조건이 분산되어있는 경우나 정렬 또는 집계가 필요한 경우 전체 범위 처리를 하지 않고는 실질적으로 필요한 부분만을 읽어 응답 속도를 줄여 줄 수 있는 부분 범위 처리가 어렵다. 이러한 문 제를 해결하기 위해 IBM의 DB2나 오라클 9i R2의 경우 Scrollable 커서를 지원하고 있지만 2-티 어 환경에서만 적용 가능하여, 3-티어와 같은 비연결 지향적인 서비스 형태를 가지는 구조에서는 이 기능을 사용할 수 없다.

액세스에 필요한 I/O를 최소화하기 위한 전략적인 테이블 설계와 인덱스의 설계가 성능 향상을 위 해 가장 중요하다. Page-Up/Page-Down 스크롤에 사용되는 정렬 기준 값으로 인덱스를 생성하고 스크롤 처리 시 인덱스를 이용한다. 인덱스는 칼럼 값으로 정렬되어 있으므로 현재 위치에서 다음 위 치로 옮겨갈 때 스크롤 조건을 SQL문에 제공하여 구현하면 불필요한 IO를 줄일 수 있다.


과다한 함수 사용으로 인한 부하 발생

저장 함수는 절차적 처리가 불가능한 SQL의 단점을 보완하기 위해 사용되는 언어이다. 목적에 맞게 효과적으로 이용하면 높은 생산성과 관리의 편리성을 제공하지만 잘못 사용하면 성능에 악영향을 미친 다. 대표적인 예가 코드명, 고객명, 상품명 등과 같이 이름 찾기 저장 함수 사용이다. 이름 찾기용 저장 함수는 프로그램 구조가 단순해져 편리성 측면에서 사용될 수는 있겠지만 DBMS 측면에서 보면 아주 비효율적인 개발 방법이다.

저장 함수는 where 조건을 만족하는 로우의 수만큼 실행되기 때문에 처리 범위가 넓은 경우 많은 비 효율이 발생하게 된다. 1,000개의 결과를 반환하는 SQL에 하나의 저장 함수를 사용하면 SQL을 한 번 수행할 때마다 저장 함수를 1,000번 호출한다.

[그림 5-3-11] 저장 SQL 구조

그리고 SQL 엔진과 절차적인 처리를 위한 PL/SQL 엔진이 분리되어 있으므로 SQL 엔진에서 처리 한 결과를 절차적으로 처리하려면 결과 값을 PL/SQL엔진으로 전송해 주어야 한다. 이러한 과정을 문 맥 전환(Context Switching)이라 하며, PL/SQL의 성능이 저하되는 주요한 원인이다. 이러한 문맥 전환을 없애기 위해서는 절차적인 부분 대신 조인 연산을 통해 처리해야 한다.

저장 함수는 다음과 같은 경우에 효과적으로 이용될 수 있다.


  • 결과 행 중 일부에서 행에 대해 복잡한 연산이 필요한 경우
  • 집계 부분으로 인해 전체 범위 처리로 수행되는 있는 SQL을 부분 범위 처리로 변경하고자 하는 경우
  • 복잡한 계산 처리가 자주 변경되어 이를 통합 관리할 필요가 있는 경우(단, 과도한 함수 호출이 예 상되는 업무에 적용할 경우 부하를 감수해야 한다)

배치 프로그램의 성능 개선

데이터베이스에서 배치 프로그램의 성능 개선은 처리 시간의 최소화에 가장 큰 목적이 있다. IT 기 술이 발전하고 정보의 활용 요구가 증가하면서 데이터 량은 기하급수적으로 증가하고 있다. 단순히 업 무 수행을 위한 데이터 증가뿐만 아니라 DW, 고객, 상품, 수익 등을 대상으로 분석에 활용하기 위한 정보량도 증가하였다. 처리해야 할 데이터량이 증가하게 되어 배치 작업, ETL, 마트 생성 등을 처리하 기 위한 방안이 제시되어야 할 시점이다. 일부에서는 배치 작업을 위한 전용 서버??서 이슈화 되는 대표적인 요소는 다음과 같다.


  • 절대 수행 시간 부족
  • 수행 결과 검증 시간 확보의 어려움
  • 오류에 따른 재처리 시간 확보가 불가능
  • 미완료 시 대안 제시에 어려움
  • 미처리 또는 지연으로 파급되는 문제 해결에 장시간이 소요됨

옵티마이저가 최적화를 수행하는 단위는 SQL 단위이므로 절차적인 방식으로 작성된 프로그램의 성능 개선 작업은 개별적인 SQL 단위로 이루어져야 한다. 그런데 개별적인 SQL의 최적화를 수행한 다고 해서 전체적인 프로그램의 최적화가 이루어지는 것은 아니므로 전체적인 최적화를 위해서는 절 차적인 프로그램을 집합적인 형태로 변경하여야 한다.

[그림 5-3-12] 절차적 처리 vs 집합적 처리


절차적인 처리 방식의 비효율
  • SQL이 루프 내에서 반복적으로 수행되는 구조이므로 DBMS call이 과도하게 발생한다.
  • 단위 SQL이 반복적으로 수행되는 구조이므로 Random I/O 발생이 증가한다.
  • 동일 데이터를 반복해서 읽는다.
  • 업무 규칙을 절차적으로 구성하였기 때문에 업무 규칙이 변경되면 프로그램 구조의 수정이 불가피하다.
  • 다수의 단위 SQL로 구성되어 있어 개별적인 단위 SQL의 개선만 가능하다.
절차적인 처리방식의 보완 요소
  • 이중 커서 사용을 하지 않고 조인을 이용하여 단일 커서를 사용한다.
  • 동일 모듈 내에서는 같은 데이터를 2회 이상 읽지 않게 프로그램을 구조화한다.
  • 최소한 개별적인 SQL 단위 비효율은 제거한다.
집합적인 처리방식의 고려사항

집합적 처리란 사용자가 기술한 SQL을 한 번의 DBMS Call로 결과 집합(Result Set)을 생성하는 DBMS 연산을 의미한다. 사용자는 결과 집합(WHAT)을 정의하고 DBMS는 처리 절차(How)를 결정 하므로 집합적인 처리 방식을 사용하려면 다음과 같은 사항을 고려해야 한다.


  • DBMS는 실행 계획을 수립하기 위한 내부적인 매커니즘을 가지고 있지만 옵티마이저의 지능적 한 계나 정보의 부족 등 여러 가지 변수에 의하여 최적의 실행 계획을 수립하지 못하는 경우가 많이 발 생하므로 SQL 작성 후 원하는 방식으로 실행 계획이 수립되었는지 반드시 확인하여야 한다.
  • 대량 배치 처리와 같이 대용량 데이터를 처리해야 하는 경우는 Hash 조인을 사용하는 것이 유리한다.
  • 분포도가 나쁘면 Random IO 비효율이 급속도로 증가하므로 인덱스 스캔보다 Table full scan 방식이 유리하다.
  • 절대적인 작업량이 정해져 있는 대용량 데이터 처리 시 병렬 처리(parallel processing)을 사용하 여 처리 시간을 단축한다.
  • Hash 조인이나 집계를 위한 소트 작업을 고려하여 추가 메모리를 세션에 할당한다. 집합 처리에 의한 작업은 병행 처리, Full scan, 메모리 영역 확보 등으로 짧은 시간에 데이터베이 스의 자원을 확보하여 처리를 해야 한다. 따라서 작업의 종속성을 고려하여 배치 프로그램 작업 계획 을 수립하여 자원의 경합을 낮춰야 한다.

배치 프로그램의 성능 개선 방안

분석 함수(Analytic Function)를 통한 성능 개선 방안

초기 RDBMS는 집합 처리의 장점이 있었지만 포인터(Pointer)와 오프셋(Offset)에 대한 연산을 할 수 없는 것이 단점이었다. 따라서 표준 SQL로는 이와 관련된 연산을 하지 못했다. 이른 이유로 절차적 언어를 사용하거나 데이터를 복제하여 처리할 수 있는 SQL문을 작성하였다.

Red Brick은 데이터 분석이나 DSS(Decision-Support System)에 적합한 다양하고 강력한 기 능을 가진 SQL 문법을 제안하였다. 이 제안에는 집합적 개념인 표준 SQL문에서 처리가 어려워 절 차적으로 처리할 수밖에 없었던 업무 분석 요구를 수용하기 위해 포인터(Pointer)와 오프셋(offset)의 개념을 추가시킨 다양한 분석 함수의 다양한 기능을 포함한다.

분석 함수를 지원하는 관계형 데이터베이스를 사용하는 경우 자체 조인(Self-join) 또는 클라이언 트 프로그램의 절차적 로직으로 처리하거나 SQL문으로 표현하기 위해 고난도의 여러 기법을 적용 하였던 것을 Native SQL문에서 하나의 명령어로 바로 적용할 수 있게 되어 개발자가 명백하고 간 결한 SQL문으로 복잡한 분석 작업을 수행할 수 있으며, 개발 및 유지 보수가 편하므로 생산력이 향 상되었다. ANSI 표준 SQL로 채택되어 대부분의 데이터베이스에서 동일한 SQL 문법을 사용할 수 있다.

다음은 상용 데이터베이스인 오라클에서 제공하는 분석 함수들이다.


Ranking Family

대상 집합에 대하여 특정 칼럼(들) 기준으로 순위나 등급을 매기는 분석 함수 그룹으로, 다음과 같 은 종류가 있다. 예를 들어 RANK, DENSE_RANK, CUME_DIST, PERCENT_RANK, NTILE, ROW_NUMBER 등이 있다.


Window Aggregate Family

현재 행(current row)을 기준으로 지정된 윈도우(window) 내의 행들을 대상으로 집단화 (aggregation)를 수행하여 여러 가지 유용한 집계 정보(running summary, moving average 등)를 구하는 분석 함수군이다. SUM, AVG, MIN, MAX, STDDEV, VARIANCE, COUNT, FIRST_VALUE, LAST_VALUE 등이 있다.


Reporting Aggregate Family

서로 다른 두 가지의 집계 레벨을 비교하고자 하는 목적으로 사용하는 분석 함수군이다. SUM, AVG, MAX, MIN, COUNT, STDDEV, VARIANCE 등이 있다.


LEAD/LAG Family

서로 다른 두 행 값을 오프셋(Offset)으로 비교하기 위한 분석 함수이다. LEAD, LAG가 있다.


파티션 스토리지 전략을 통한 성능 향상 방안

대용량의 데이터를 신속하게 처리하기 위해서는 파티셔닝(분할)과 같은 스토리지 전략이 중요하 다. 파티셔닝은 대용량의 큰(지속적으로 증가하는) 테이블을 파티션이라는 보다 작은 단위로 나눔으 로써 성능이 저하되는 것을 방지하고 관리를 보다 수월하게 하고자 하는 개념이다. 파티셔닝은 칼럼 단위의 수직 파티션을 제공하고 있는 사이베이스를 제외한 DB2, 인포믹스, 오라클 등과 같은 대용 량의 데이터베이스 상용 벤더들은 범위 파티션(Range Partition)과 같이 유사한 형태의 파티션을 제공한다. 파티셔닝을 하게 되면 하나의 테이블이 동일한 논리적 속성을 공유하는 여러 개의 단위(파 티션)로 나눠지게 된다. 각 파티션은 열(Column)과 제약 조건에 대한 정의를 공유하지만 별도의 세 그먼트로 저장되어 물리적인 속성인 블록 파라미터나 스토리지 파라미터를 독립적으로 지정할 수 있 다. 이러한 특성으로 파티셔닝 테이블은 다음과 같은 장점이 있다.


  • 데이터 액세스 시에 파티션 단위로 액세스 범위를 줄여 I/O에 대한 성능 향상을 가져올 수 있다.
  • 여러 분할 영역으로 나눔으로써 전체 데이터의 훼손 가능성이 감소하고 데이터의 가용성이 향상된다.
  • 각 분할 영역을 독립적으로 백업하고 복구할 수 있다.
  • 디스크 스트라이핑으로 I/O 성능을 향상(디스크 암에 대한 경합의 감소)시킬 수 있다.