SQL 성능 최적화 - 대량 데이터 조회 & API 응답 속도 개선 방법

Berkley·2025년 2월 23일
0

📝 서론

이번 포스팅에서는 프론트엔드에서 필요한 데이터 값을 받아오는 방식으로 조회 성능의 대해 다뤄보고자 한다. 이는 API로 통칭하며, API 받아오는 성능을 최적화 하는 방법의 대해 알아보고자 한다.

🔍 API 란?

  • API: Application Programming Interface
  • 이는 인터페이스 중 하나의 일종으로 다른 서비스의 기능을 빌려서 사용할 수 있도록 도와주는 도구 라고도 한다.
  • 기본적으로 HTTP 프로토콜을 이용하여 데이터를 주고 받는 형식이라고 설명 할 수 있다.

📊 API 성능 측정

  • API 성능 측정하는 방식은 여러 가지 있지만, 주로 조회 조건의 구조에 따라 성능이 크게 반영한다.
  • 백엔드 개발자 입장에서는 SQL문 방식이나 파일 입출력을 이용하여 데이터를 조회한 후,
    프론트엔드에게 필요한 데이터를 가공하여 전달한다.
  • SI 프로젝트의 경우, 대부분 SQL문에서 직접 조회하여 처리하는 방식이 일반적이다.
  • 하지만, 대량 데이터 조회 시 SQL에서만 처리하면 성능 문제가 발생할 수 있다.
    (예: LIKE 검색 남발, 불필요한 조건 사용, 인덱스 없는 조회 등)

🚀 API 성능 개선 방법

  • 이 블로그에서 조회 문의 대한 결과를 수행하는 경우의 대해 다뤄보고자 한다.

✅ SQL만 사용하여 조회하면 직관적이고 명확하지만,
❌ LIKE 문 남발, 불필요한 조건 사용, 대량 데이터 조회 시 성능 저하 문제가 발생할 수 있다.

💡 해결 방법:
1️⃣ SQL에서 1차 필터링 (가장 중요한 필터만 남기기)
2️⃣ 애플리케이션에서 2차 필터링 (LIKE 검색, 정규식, 복잡한 로직)

🔎 조회 최적화 전략

SQL문 쿼리 - 1차 필터링 (O(log N))

SQL 문은 최대한 단순하게 구성하고, 1차 필터링 역할만 수행해야 한다.
LIKE 검색이 들어가지 않는 조건을 SQL에서 처리한다.

SQL 필터링 대상
조건절: LIKE 없이 필터링 가능한 것만 남기기.
상태값 (IN, =): 필터링할 때 IN ('FAILED', 'TIMEOUT') 같은 명확한 조건 사용.
인덱스 활용: user_id, user_code 같은 숫자 기반 필터링 우선.
날짜 범위: log_date >= NOW() - INTERVAL 30 DAY (명확한 범위 사용).
정렬 (ORDER BY): SQL에서 가능한 경우 활용, 불가능하면 애플리케이션에서 정렬.

애플리케이션(JAVA, NODE.JS, PYTHON 등) - 2차 필터링 (O(N))

SQL에서 1차로 필터링한 데이터를 애플리케이션에서 추가 가공
복잡한 문자열 검색, 정규식, LIKE 검색은 애플리케이션에서 처리

애플리케이션에서 필터링할 대상
특정 단어 포함: LIKE 대신 Java의 .contains() 활용
특정 패턴 매칭: 정규식(matches()) 사용
IP 주소 범위 검색: .startsWith() 활용
복잡한 비즈니스 로직: SQL로 불가능한 경우 애플리케이션에서 처리

🚀 코드 예시 (SQL + 애플리케이션 최적화)

  • 로그 데이터 조회하는 API 개발 기준 예시
  • 데이터가 500만개 이상인 경우 가정

SQL문

  • SQL에서 1차 필터링 (날짜 + ID + 상태값, LIKE 제외)
SELECT * FROM logs
WHERE log_date >= NOW() - INTERVAL 30 DAY  -- 최근 30일 데이터
AND user_id = 1234                         -- 특정 사용자
AND status IN ('FAILED', 'TIMEOUT')        -- 특정 상태
ORDER BY log_date
LIMIT 100000;

SQL에서 가능한 한 많은 데이터를 필터링 (WHERE + INDEX)
LIKE '%keyword%'는 SQL에서 하지 않음 → Application 에서 처리

Application 층 (Java)

  • 애플리케이션(JAVA)에서 2차 필터링 (LIKE, 정규식, 복잡한 로직 등)
List<Map<String, Object>> filteredLogs = logs.stream()
    .filter(log -> ((String) log.get("message")).contains("error")) // 특정 키워드 포함
    .filter(log -> ((String) log.get("ip_address")).startsWith("192.168.")) // 특정 IP 대역
    .filter(log -> ((String) log.get("extra_data")).matches("^\\d{4}-.*$")) // 정규식 필터링
    .collect(Collectors.toList());

SQL에서 가져온 데이터 중 Java에서 LIKE 검색 및 추가 필터링
정규식이나 패턴 검색이 필요한 경우 Java에서 처리하는 것이 성능적으로 유리

🚀 결론 : SQL + Application의 역할 분리

✔ SQL에서 1차 필터링 (WHERE + INDEX)
✔ Application(JAVA)에서 2차 필터링 (contains(), 정규식, 복잡한 로직)
✔ 대량 데이터 조회 시 성능 최적화 필요 (SQL에서 모든 걸 처리하면 안 됨)

💡 최적화 핵심

1️⃣ SQL에서 WHERE + INDEX로 최대한 필터링
2️⃣ 애플리케이션에서 복잡한 문자열 검색, 정규식 처리
3️⃣ SQL에서 LIKE '%keyword%' 사용 금지 → 애플리케이션에서 .contains()로 처리

🔹 대량 데이터(100만 개 이상)에서는 Elasticsearch 같은 검색 엔진도 고려할 것
🔹 SQL에서 너무 많은 연산을 하지 말고, 애플리케이션과 역할을 나눠야 성능이 최적화됨

이제 SQL과 애플리케이션을 분리하여 성능 극대화 가능하다!!

#SQL 성능 최적화, #API 조회 속도 개선, #Like 검색 성능 문제, #대량 데이터 처리, #Java에서 SQL 최적화, #API 최적화 방법

profile
성장하는 개발자 Berkley 입니다.

0개의 댓글