[MongoDB] Query 성능 최적화 (Aggregation)

기훈·2024년 4월 2일

MongoDB

목록 보기
11/28

(지금부터 서술하는 글은 모든 해당사항에 적용되지 않는다)

lookup을 사용하기 전에 sort나 limit을 먼저 진행하자.

MongoDB의 쿼리 성능을 최적화하는 데 있어 sort나 limit 같은 연산을 $lookup 이전에 수행하는 것이 성능에 이점을 줄 수 있다. 이유는 데이터 처리 파이프라인의 효율성과 관련이 있다.

MongoDB의 Aggregation Framework는 데이터를 파이프라인을 통해 처리하는데, 이 파이프라인은 여러 단계로 구성되며 각 단계는 입력을 받아 처리 후 그 결과를 다음 단계로 전달한다. 여러분이 $lookup을 사용해 조인 작업을 하기 전에 $sort나 $limit을 사용하면, 조인 작업에 필요한 데이터의 양을 줄일 수 있다. 이로 인해 전체적으로 처리해야 할 데이터의 양이 줄어들고, 따라서 쿼리 성능이 향상될 수 있다.

  • $sort 먼저 사용: 데이터를 정렬하기 전에 필요한 데이터만 추출하거나 줄여서, 정렬해야 할 데이터의 양을 최소화한다. 이는 특히 인덱스를 활용할 수 있을 때 더욱 유리하다.

  • $limit 먼저 사용: $limit을 적용함으로써 처리해야 할 데이터의 양을 대폭 줄일 수 있다. 이는 $lookup으로 가져와야 할 데이터의 양이 많을 때 특히 중요하다. 필요한 데이터의 수를 제한함으로써 조인되는 컬렉션의 크기를 사실상 줄이는 효과를 낼 수 있다.

db.orders.aggregate([
  // 첫 번째 단계: 각 주문별 총 아이템 수량 계산
  {
    $addFields: {
      totalQuantity: { $sum: "$items.quantity" } // items 배열의 각 항목에서 quantity 필드를 합산
    }
  },
  
  // 두 번째 단계: 계산된 총 아이템 수량에 따라 내림차순으로 정렬
  { $sort: { totalQuantity: -1 } },

  // 세 번째 단계: 상위 5개의 주문만 선택
  { $limit: 5 },

  // 네 번째 단계: products 컬렉션에서 각 주문의 아이템 상세 정보를 조인
  {
    $lookup: {
      from: "products",
      localField: "items.productId",
      foreignField: "_id",
      as: "productDetails"
    }
  },
  
  // 다섯 번째 단계: 결과를 어떻게 표시할지 추가 정의
  {
    $project: {
      _id: 1,
      orderDate: 1,
      totalQuantity: 1,
      items: 1,
      productDetails: 1
    }
  }
]);

(TIP) 가공된 필드가 아닌 기본필드인 경우, 내부적으로 lookup 전에 sort, limit을 내부적을 처리한다.

0개의 댓글