[Open WebUI] 메시지 전송마다 발생하는 불필요한 채팅 JSON 역직렬화 2회 제거
PR 링크: open-webui/open-webui#21596 상태: Merged | 변경: +42 / -6
들어가며
Open WebUI에서 메시지를 보낼 때마다 get_chat_by_id_and_user_id가 두 번 호출되었습니다. 이 함수는 Chat 테이블의 전체 행을 로드하는데, 여기에는 대화 전체 히스토리가 담긴 거대한 JSON 블록이 포함됩니다. 긴 대화(도구 호출, 이미지, 파일 첨부 포함)에서 이 JSON은 수 MB에 달할 수 있습니다. 하지만 실제로 필요한 정보는 "이 채팅이 존재하는가?"와 "folder_id 값이 무엇인가?" 뿐이었습니다.
핵심 코드 분석
소유권 확인: 전체 로드에서 EXISTS 쿼리로
Before (main.py):
chat = Chats.get_chat_by_id_and_user_id(metadata["chat_id"], user.id)
if chat is None and user.role != "admin":
raise HTTPException(...)
After:
if not Chats.is_chat_owner(metadata["chat_id"], user.id) and user.role != "admin":
raise HTTPException(...)
새로 추가된 is_chat_owner 메서드:
def is_chat_owner(self, id: str, user_id: str, db=None) -> bool:
with get_db_context(db) as db:
return db.query(
exists().where(
and_(Chat.id == id, Chat.user_id == user_id)
)
).scalar()
폴더 조회: 전체 로드에서 단일 컬럼 조회로
Before (middleware.py):
chat = Chats.get_chat_by_id_and_user_id(chat_id, user.id)
if chat and chat.folder_id:
folder = Folders.get_folder_by_id_and_user_id(chat.folder_id, user.id)
After:
folder_id = Chats.get_chat_folder_id(chat_id, user.id)
if folder_id:
folder = Folders.get_folder_by_id_and_user_id(folder_id, user.id)
새로 추가된 get_chat_folder_id 메서드:
def get_chat_folder_id(self, id: str, user_id: str, db=None):
with get_db_context(db) as db:
result = (
db.query(Chat.folder_id)
.filter_by(id=id, user_id=user_id)
.first()
)
return result[0] if result else None
왜 이게 좋은가
- 메시지 전송마다 수 MB 크기의 JSON blob을 2번 역직렬화하던 것이 완전히 제거됩니다
EXISTS쿼리는 행 데이터를 로드하지 않고 프라이머리 키 인덱스만으로 결과를 반환합니다db.query(Chat.folder_id)는 SQLAlchemy에SELECT folder_id만 생성하도록 지시합니다- Pydantic의
model_validate오버헤드도 제거됩니다 - 대화가 길어질수록 효과가 더 커지는 최적화입니다
참고 자료
관련 포스트
PR Analysis 의 다른글
- 이전글 [faster-qwen3-tts] 모드 간 성능 동등성 검증 및 벤치마크 비교 문서화
- 현재글 : [Open WebUI] 메시지 전송마다 발생하는 불필요한 채팅 JSON 역직렬화 2회 제거
- 다음글 [Grafana Loki] 블룸 필터 캐시를 맵으로 교체하여 운영 복잡도 제거
댓글