DevLog

엔지니어링 블로그를 한 곳에서 탐색하고, 최근 발행 흐름을 빠르게 파악할 수 있는 서비스 입니다.

Quick Links

  • Latest Feed
  • Engineering Directory

Support

  • 소개
  • 개인정보처리방침

Contribute

  • 원하는 블로그 추가 (준비 중)
  • Feedback

© 2026 DevLog Inc. All rights reserved.

본 사이트는 공개 RSS 피드를 통해 콘텐츠를 수집하며, 모든 콘텐츠의 저작권은 원저작자에게 있습니다.

Back to Feed
Read Original

Contents

Continue Reading

  • More from 채널 톡
#Backend

biz-crm IndexedDAO 적용기

biz-crm IndexedDAO 적용기
01

Summary

"8초 걸리던 검색이 0.2초 만에?" 무분별한 LOWER() 쿼리를 잡고 성능을 40배 올린 IndexedDAO 도입기

기술적 튜닝보다 먼저 사용자의 목소리에서 해답을 찾은 채널톡의 고객 중심 성능 최적화 전략

백오피스 서비스의 고질적인 대용량 데이터 검색 성능 문제를 해결하기 위해, 기술적 접근에 앞서 사용자 인터뷰로 실제 활용 패턴을 도출했습니다. 인덱스 무력화의 주범인 대소문자 무시 쿼리를 개선하고, 인덱스 히트를 보장하는 IndexedDAO 패턴을 설계하여 서비스 안정성과 성능을 획기적으로 개선한 여정을 담고 있습니다.

  • 011,000만 건 테이블에서 Full Table Scan을 유발하던 JOOQ의 .equalIgnoreCase() 패턴 분석
  • 02사용자 인터뷰를 통해 복잡한 다중 필터 기능이 아닌 특정 ID 중심의 검색이 주된 패턴임을 확인
  • 03Function-based Index 도입 대신 유지보수와 비용 측면에서 유리한 IndexedDAO 추상화 계층 설계
  • 04SearchRequest DTO를 이용해 인덱스 활용 여부를 컴파일 단계에서 명시적으로 관리
  • 05쿼리 응답 속도 97.5% 개선 및 성능 문제가 반복되지 않는 구조적 해결책 마련

+RECOMMENDATION

대용량 RDB 환경에서 동적 쿼리 사용으로 인해 인덱스 효율이 떨어져 고민하는 백엔드 개발자들에게 강력히 추천합니다. 특히 JOOQ나 Querydsl 같은 ORM 환경에서 인덱스를 안전하게 타는 추상화 레이어를 고민할 때 좋은 참고가 될 것입니다.

The Problem

biz-crm 백오피스 서비스에서 대용량 테이블(1,000만 건 이상) 검색 시, JOOQ의 대소문자 무시 검색 기능이 LOWER() 함수를 컬럼에 적용하여 인덱스를 무력화하고 Full Table Scan을 유발함으로써 6초 이상의 응답 지연과 타임아웃을 발생시켰다.

The Solution

사용자 인터뷰를 통해 복잡한 범용 필터 대신 특정 채널 ID 기반의 단순 검색이 주된 패턴임을 파악하고, 특정 인덱스 활용을 강제하도록 쿼리 생성 책임을 분리한 'IndexedDAO' 패턴과 SearchRequest DTO 구조를 도입했다.

The Result

8초 이상 소요되던 특정 쿼리의 응답 시간을 200ms 수준으로 단축하였으며, 인덱스 히트를 보장하는 추상화된 DAO 레이어를 구축하여 다른 대용량 테이블에도 적용 가능한 재사용성 높은 아키텍처를 확보했다.

Trade-off

성능 최적화를 위해 기존의 유연한 범용 다중 필터 기능을 일부 제한하고 특정 조회 조건 사용을 강제했으며, 새로운 검색 기능 추가 시마다 전용 DTO와 DAO를 정의해야 하는 추가적인 구현 공수가 발생한다.

03

Key Concepts

Concept · 01

Full Table Scan

인덱스를 사용하지 못하고 테이블의 모든 레코드를 처음부터 끝까지 조회하여 결과를 찾는 방식으로, 데이터가 많아질수록 성능이 급격히 저하된다.

  • LOWER() 함수가 컬럼에 적용되어 인덱스를 타지 못할 때 발생하며, 본문에서 6초 이상의 지연을 유발한 근본 원인이다.
Concept · 02

IndexedDAO Pattern

성능이 중요한 대용량 테이블 조회 시, 인덱스를 타는 특정 필드만을 검색 조건으로 사용하도록 강제하고 추상화한 데이터 접근 패턴이다.

  • 범용적인 JooqExpressionConverter 대신 SearchRequest DTO를 통해 인덱스 히트가 보장되는 쿼리만 생성하도록 책임을 분리했다.
Concept · 03

Customer-driven

단순히 요청된 기능을 개발하는 것을 넘어, 사용자가 제품을 실제로 사용하는 방식과 맥락을 파악하여 문제 해결의 본질적인 단서를 찾는 태도이다.

  • 과도한 기술적 튜닝에 앞서 CX팀 인터뷰를 통해 복잡한 검색 필터 기능의 불필요함을 파악하고 최적화 방향을 설정하는 핵심 기준이 되었다.
Continue reading · same source

채널 톡More from 채널 톡

View all posts from 채널 톡
  • [신청 중] AI Product Frontiers: AI 시대, 최전선에서 방향을 만드는 사람들

    MeetupAI InfrastructureArtificial Intelligence
    2일 전
  • 채널콘 2026 디자인 비하인드

    FramerGenerative AILocalization
    2일 전
  • Swift 6 어때요? (1): 스레드, 블록, 태스크

    Swift ConcurrencyGCDRxSwift
    2일 전
  • 5년, 340개의 이야기로 이어온 개발 문화

    Developer RelationsKnowledge SharingEngineering Culture
    3일 전
  • 유저챗 개인정보 마스킹 개발기

    RegexRE2ReDoS
    4일 전

Source

채널 톡
채널 톡
Engineering Blog

Published · March 5, 2026

Topics

IndexedDAOJOOQDatabase IndexingBackend PerformanceQuery Optimization