인덱스와 쿼리 속도

2025년 2월 6일 목요일

Today I Learned

날짜

2025년 2월 6일 목요일

내용

is와 ==의 차이

네이버 커머스 솔루션 관련 버그를 고치던 중, 네이버 스토어 데이터에도 샵의 비활성화 여부를 나타내는 필드를 추가해야 했다. 따라서 NaverStore 테이블에 is_active 필드를 추가했다. 이제 스토어를 탐색하는 경우의 대부분은 ‘활성화된 스토어’를 기준으로 하는게 당연해졌으므로 탐색 함수에 is_active 필드가 True인 경우를 추가해줬다. 따라서

1
2
3
stmt = select(models.NaverStore).where(
	models.NaverStore.is_active == True
)

이런식으로 쿼리를 작성했다. 그런데 Flake8에서 경고 메시지가 떴다.

1

== 연산자 대신 is 사용을 쓰라는건가? 별걸 다 갖고 참견하나 싶었는데, 이참에 ==is를 비교해봤다.

is 연산자 (동일성 비교) == 연산자 (값의 동등성 비교)
실제로 불리언 True인지 (다른 값이 아니라) 확인 값이 True와 같다고 평가되는지를 검사
객체의 동일성(identity) 값의 동등성(equality)

똑같은 지와 동등한 지의 차이다.

따라서

1
2
3
4
5
6
7
8
9
10
11
12
t = True
one = 1

print(t is 1)  # False
print(t == 1)  # True
print(t is True)  # True
print(t == True)  # True

print(one is 1)  # True
print(one == 1)  # True
print(one is True)  # False
print(one == True)  # True

인덱스 지정으로 쿼리 속도 높이기

쇼피파이 웹훅이 많이 안정화되었으나, 여전히 요청 처리가 느리다. Sentry에서 구체적인 쿼리 속도를 살펴봤다.

2

확대해서 보면 get_shopify_store_by_platform_shop_url 요청이 평균적으로 2.22초나 걸린다. 뭔 함수가 저렇게나 걸리나..

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def get_shopify_store_by_platform_shop_url(
    myshopify_domain: str,
    db: Session,
):
    """
    Shopify Store 정보를 가져옵니다.
    """
    stmt = select(models.ShopifyStore).where(
        models.ShopifyStore.myshopify_domain == myshopify_domain
    )
    shopify_store = db.execute(stmt).scalar()
    if not shopify_store:
        return None
    return shopify_store

전혀 복잡하지 않은 함수다. 그냥 myshopify_domain 으로 쇼피파이 스토어 데이터를 찾는 함수일 뿐인데… 이 함수의 속도를 높이기 위해 저 필드를 index로 지정하려 한다.

  1. 웹훅에서 사용되는 함수이므로 상당히 자주 쓰이고,
  2. myshopify_domain 은 쇼핑몰마다 고유한 값을 가지므로 index로서 기능을 충분히 할 수 있다

고 판단했기 때문이다

1
2
3
4
5
class ShopifyStore(Base):
    ...
    myshopify_domain = Column(
        TEXT, index=True
    )  # shopify에서 고정된 myshopify.com 도메인

하루가 지나고 속도 변화를 살펴봤다.

3

22200ms ⇒ 822ms 로 감소했다. 굿.

회고

눈이 많이온다. 내일은 출근이 쉽지 않겠다.