본문으로 건너뛰기

[Open WebUI] Knowledge 파일 배치 추가 시 N+1 쿼리 제거

PR 링크: open-webui/open-webui#21006 상태: Merged | 변경: +12 / -10

들어가며

Open WebUI의 Knowledge(지식 베이스) 기능에서 여러 파일을 한 번에 추가하는 add_files_to_knowledge_batch 엔드포인트에 N+1 쿼리 문제가 있었습니다. 파일을 10개 추가하면 데이터베이스 쿼리가 10번 발생하는 구조였으며, 파일 수가 늘어날수록 응답 시간이 선형적으로 증가하는 문제가 있었습니다.

핵심 코드 분석

Before: 파일당 개별 쿼리 (N+1)

files: List[FileModel] = []
for form in form_data:
    file = Files.get_file_by_id(form.file_id, db=db)
    if not file:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"File {form.file_id} not found",
        )
    files.append(file)

파일 ID 목록을 순회하면서 get_file_by_id를 각각 호출합니다. 파일이 N개면 N번의 DB 쿼리가 발생합니다.

After: SQL IN 절로 단일 쿼리

file_ids = [form.file_id for form in form_data]
files = Files.get_files_by_ids(file_ids, db=db)

# Verify all requested files were found
found_ids = {file.id for file in files}
missing_ids = [fid for fid in file_ids if fid not in found_ids]
if missing_ids:
    raise HTTPException(
        status_code=status.HTTP_400_BAD_REQUEST,
        detail=f"File {missing_ids[0]} not found",
    )

get_files_by_ids로 SQL IN 절을 사용하여 한 번의 쿼리로 모든 파일을 조회합니다. 누락된 파일 검증도 set 연산으로 O(1) 조회합니다.

왜 이게 좋은가

  1. 쿼리 수 감소: N+1번의 쿼리가 1번으로 줄어듭니다. 파일 100개를 추가할 때 100번의 DB 왕복이 1번으로 감소합니다.
  2. 네트워크 오버헤드 감소: DB 서버가 원격에 있을 경우 각 쿼리마다 발생하는 네트워크 레이턴시가 누적되지 않습니다.
  3. 검증 로직 개선: set 기반 검증으로 누락 파일을 O(N) 대신 O(1)로 확인합니다.

N+1 쿼리 문제는 ORM 사용 시 가장 흔하게 발생하는 성능 안티패턴이며, 이 PR은 배치 조회 패턴으로 깔끔하게 해결한 좋은 사례입니다.

참고 자료

댓글

관련 포스트

PR Analysis 의 다른글