본문 바로가기

카테고리 없음

복잡한 쿼리 비교 (in과 exist)

N(SummaryUrl):M(SummaryWorkspace) 관계를 가운데에 map 테이블을 두었다.


1(SummaryUrl):N(MapSummaryWorkspaceUrl)     N(MapSummaryWorksapceUrl): 1(SummaryWorkspace)

관계에서

주어진 workspace_code_uid에 해당하는 SummaryUrl을 조회하는 방법 

 

A방식 in 쿼리를 쓰면 좋은 경우 

✅ MapSummaryWorkspaceUrl 테이블이 작을 때
✅ workspace_code_uid로 필터했을 때 결과 row 수가 매우 적을 때
✅ 인덱스가 아주 잘 잡혀 있을 때

 

 

B방식 exist 쿼리를 쓰면 좋은 경우 

✅ 데이터가 많아질수록
✅ 하나의 URL이 여러 workspace에 연결될수록
✅ pagination이 정밀해야 할수록

 

= 일반적 경우의 index라면 B 방식이 훨씬 좋음  

 

A 방식 (in)

a = (
    select(MapSummaryWorkspaceUrl.smyurl_uid)
    .where(MapSummaryWorkspaceUrl.smywks_code_uid == workspace_code_uid)
    .subquery()
)

filters = [
    SummaryUrl.cpn_code_uid == company_code_uid,
    SummaryUrl.smyurl_deleted_at.is_(None),
]
if url_name:
    filters.append(SummaryUrl.smyurl_name.ilike(f"%{url_name}%"))
if url_url:
    filters.append(SummaryUrl.smyurl_url.ilike(f"%{url_url}%"))

b = (
    select(SummaryUrl)
    .where(*filters, SummaryUrl.smyurl_uid.in_(a))
    .offset(page * limit)
    .limit(limit)
    .order_by(desc(SummaryUrl.smyurl_updated_at))
)

 

 

B방식 (exist)

if workspace_code_uid:
    filters.append(
        exists(
            select(1)
            .select_from(MapSummaryWorkspaceUrl)
            .where(
                and_(
                    MapSummaryWorkspaceUrl.smyurl_uid
                    == SummaryUrl.smyurl_uid,
                    MapSummaryWorkspaceUrl.smywks_code_uid
                    == workspace_code_uid,
                )
            )
        )
    )
    result_stmt = (
        select(SummaryUrl)
        .where(*filters)
        .order_by(desc(SummaryUrl.smyurl_updated_at))
        .offset(page * limit)
        .limit(limit)
    )