요약 정리

데이터베이스 성능 최적화: 인덱스와 쿼리 튜닝

코드로 칼퇴하기 2024. 5. 25. 11:09

데이터베이스 성능 최적화란?

데이터베이스 성능 최적화(Database Performance Optimization)는 데이터베이스 시스템의 효율성을 극대화하여 데이터 저장, 검색 및 처리 속도를 향상시키는 과정입니다. 성능 최적화는 데이터베이스 응답 시간을 줄이고, 시스템 자원을 효율적으로 사용하며, 사용자 경험을 향상시키는 데 중요한 역할을 합니다.

인덱스란?

인덱스(Index)는 데이터베이스 테이블의 검색 성능을 향상시키기 위해 사용하는 데이터 구조입니다. 인덱스는 테이블의 특정 열에 대한 포인터 목록을 포함하며, 검색 속도를 빠르게 하는 데 도움을 줍니다.
인덱스의 장점

  1. 빠른 데이터 검색
    • 인덱스를 사용하면 데이터베이스에서 원하는 데이터를 더 빠르게 검색할 수 있습니다.
  2. 효율적인 정렬
    • 인덱스를 사용하면 데이터 정렬 작업이 효율적으로 수행됩니다.
  3. 고유성 보장
    • 고유 인덱스를 사용하면 중복 데이터를 방지하고 데이터의 무결성을 보장할 수 있습니다.

인덱스의 단점

  1. 추가 저장 공간 필요
    • 인덱스는 추가적인 저장 공간을 사용합니다.
  2. 데이터 수정 시 성능 저하
    • 데이터 삽입, 수정, 삭제 시 인덱스를 업데이트해야 하므로 성능이 저하될 수 있습니다.

인덱스 예제 (MySQL)

-- 기본 인덱스 생성
CREATE INDEX idx_column_name ON table_name (column_name);

-- 고유 인덱스 생성
CREATE UNIQUE INDEX idx_unique_column_name ON table_name (column_name);

-- 복합 인덱스 생성
CREATE INDEX idx_multi_columns ON table_name (column1, column2);

테스트 데이터베이스 생성 및 인덱스 속도 차이 측정 파이썬 코드

속도 차이 측정(20393배)
import sqlite3
import time
import pandas as pd

# 데이터베이스 연결
conn = sqlite3.connect(':memory:')
cursor = conn.cursor()

# 예제 테이블 생성
cursor.execute('''
CREATE TABLE employees (
    id INTEGER PRIMARY KEY,
    name TEXT,
    age INTEGER,
    city TEXT
)
''')

# 예제 데이터 삽입 (100만 건)
data = [(i, f'Name{i}', 20 + (i % 30), f'City{(i % 10)}') for i in range(1, 1000001)]
cursor.executemany('INSERT INTO employees VALUES (?, ?, ?, ?)', data)
conn.commit()

# 인덱스 없는 경우 검색 시간 측정 (1000회 반복)
no_index_times = []
for _ in range(1000):
    start_time = time.perf_counter()
    cursor.execute('SELECT * FROM employees WHERE name="Name5000000"')
    cursor.fetchall()
    no_index_times.append(time.perf_counter() - start_time)
no_index_avg_time = sum(no_index_times) / len(no_index_times)

# 인덱스 생성
cursor.execute('CREATE INDEX idx_name ON employees (name)')
conn.commit()

# 인덱스 있는 경우 검색 시간 측정 (1000회 반복)
index_times = []
for _ in range(1000):
    start_time = time.perf_counter()
    cursor.execute('SELECT * FROM employees WHERE name="Name5000000"')
    cursor.fetchall()
    index_times.append(time.perf_counter() - start_time)
index_avg_time = sum(index_times) / len(index_times)

# 결과 출력
results = pd.DataFrame({
    'Search Condition': ['No Index', 'With Index'],
    'Average Time (seconds)': [no_index_avg_time, index_avg_time]
})

# 몇 배 차이인지 계산
speedup = no_index_avg_time / index_avg_time if index_avg_time > 0 else float('inf')
results['Speedup'] = [1, speedup]

# 결과를 CSV 파일로 저장
results.to_csv('index_speed_comparison_revised.csv', index=False)

# 데이터베이스 연결 종료
conn.close()

print(f"Search time comparison has been saved to 'index_speed_comparison_revised.csv'. Speedup: {speedup:.2f}x")

쿼리 튜닝이란?

쿼리 튜닝(Query Tuning)은 데이터베이스 쿼리의 성능을 최적화하여 응답 시간을 줄이는 과정입니다. 잘 설계된 쿼리는 데이터베이스 성능을 크게 향상시킬 수 있습니다.
쿼리 튜닝의 주요 기법

  1. 적절한 인덱스 사용
    • 검색 조건에 맞는 인덱스를 사용하여 쿼리 성능을 향상시킵니다.
  2. 불필요한 데이터 제거
    • 필요한 데이터만 선택하고, 불필요한 데이터를 제거하여 쿼리 성능을 향상시킵니다.
  3. 조인 최적화
    • 조인(join) 연산을 최적화하여 데이터 검색 성능을 향상시킵니다.
  4. 서브쿼리 최적화
    • 서브쿼리를 사용하지 않거나, 서브쿼리를 최적화하여 성능을 향상시킵니다.

쿼리 튜닝 예제 (MySQL)

-- 기본 인덱스 생성
CREATE INDEX idx_column_name ON table_name (column_name);

-- 고유 인덱스 생성
CREATE UNIQUE INDEX idx_unique_column_name ON table_name (column_name);

-- 복합 인덱스 생성
CREATE INDEX idx_multi_columns ON table_name (column1, column2);

인덱스와 쿼리 튜닝을 통한 성능 최적화 사례

사례 1: 인덱스를 통한 성능 향상

-- 인덱스가 없는 경우
SELECT * FROM employees WHERE last_name = 'Smith';

-- 인덱스 생성
CREATE INDEX idx_last_name ON employees (last_name);

-- 인덱스를 사용한 쿼리
SELECT * FROM employees WHERE last_name = 'Smith';

사례 2: 쿼리 튜닝을 통한 성능 향상

-- 비효율적인 쿼리
SELECT * FROM sales WHERE YEAR(order_date) = 2022;

-- 최적화된 쿼리
SELECT * FROM sales WHERE order_date BETWEEN '2022-01-01' AND '2022-12-31';

성능 최적화 도구

  1. 데이터베이스 모니터링 도구
    • 데이터베이스 성능을 실시간으로 모니터링하고, 병목 현상을 식별하는 도구입니다.
    • 예: MySQL Enterprise Monitor, Oracle Enterprise Manager
  2. 쿼리 분석 도구
    • 쿼리 성능을 분석하고 최적화 제안을 제공하는 도구입니다.
    • 예: MySQL EXPLAIN, SQL Server Query Analyzer

 
데이터베이스 성능 최적화는 데이터베이스 시스템의 효율성을 극대화하여 사용자 경험을 향상시키는 데 중요한 역할을 합니다. 인덱스와 쿼리 튜닝은 성능 최적화의 핵심 기법으로, 데이터 검색 속도를 향상시키고 시스템 자원을 효율적으로 사용할 수 있도록 합니다.