한 남자가 11년 동안 전 세계를 돌아다니다 집으로 돌아왔습니다. 다음 날 아내에게 동네 구멍가게에 간다고 말하자 아내는 이렇게 물었습니다: "짧은 길로 갈 거야, 긴 길로 갈 거야?"라고 물었습니다.

쿼리는 여러 가지 방법으로 실행할 수 있습니다. 모든 경로는 동일한 쿼리 결과로 이어집니다. NoSQL 및 쿼리 최적화 도구는 가능성을 평가하고 효율적인 계획을 선택합니다. 효율성은 워크로드에 따라 지연 시간과 처리량으로 측정됩니다. 비용 기반 최적화 도구에서는 메모리, CPU, 디스크 사용량이 요금제 비용에 추가됩니다.

이제 대부분의 경우 NoSQL 데이터베이스 에는 SQL 유사 쿼리 언어 지원. 따라서 좋은 최적화 도구는 필수입니다. 좋은 최적화 도구가 없으면 개발자는 기능 제한을 감수해야 하고, DBA는 NoSQL 쿼리 성능 문제를 감수해야 합니다.

NoSQL 성능 검색을 개선하는 데이터베이스 옵티마이저

NosSQL 쿼리 최적화를 통해 최적의 인덱스와 액세스 경로를 선택하여 검색을 실행할 수 있습니다. 매우 높은 수준에서 SQL 최적화 도구는 실행 트리를 생성하기 전에 다음을 결정합니다:

  1. 휴리스틱, 비용 또는 둘 다에 기반한 쿼리 재작성.
    • 편집자가 글에서 불필요한 단어를 제거하는 것처럼 쿼리 재작성 작업은 불필요한 술어 제거부터 하위 쿼리 평탄화, 적절한 왼쪽 외부 조인을 내부 조인으로 변환, 파생 테이블 접기 등에 이르기까지 다양합니다.
  2. 색인 선택.
    • 각 테이블에 대한 최적의 인덱스 선택(Couchbase N1QL의 경우 키 공간, MongoDB 성능 모범 사례의 경우 컬렉션)
    • 선택한 인덱스에 따라 푸시다운할 술어를 선택하고, 쿼리가 포함되는지 여부를 확인하고, 정렬 및 페이지 매김 전략을 결정합니다.
  3. 재주문 참여
    • (A INNER JOIN B INNER JOIN C)는 (B INNER JOIN C INNER JOIN A)와 동일합니다. 옵티마이저는 이러한 조인의 순서를 지정하는 가장 최적의 방법을 결정해야 합니다.
  4. 조인 유형
    • 데이터베이스는 중첩 루프, 해시, 정렬 병합, 지그재그, 스타(눈송이) 등 여러 유형의 조인 알고리즘을 구현할 수 있습니다. 구조와 비용에 따라 옵티마이저는 각 조인 작업에 대한 조인 알고리즘 유형을 결정해야 합니다.

몽고DB 제한의 경우를 생각해 보세요. "컬렉션에는 최대 하나 텍스트 index."  https://docs.mongodb.com/manual/core/index-text/#restrictions 이와 함께 몇 가지 다른 제한 사항을 설명합니다. 이 글에서는 이 제한 사항 하나만 설명하는 것으로 충분합니다.

 

이 제한에 신경 써야 하는 이유는 무엇인가요?

  1. MongoDB 및 기타 NoSQL 데이터베이스에서는 스키마를 비정규화(집계)하여 고객, 파트너 등의 개체를 나타내는 하나의 큰 문서를 만들어 대부분의 작업이 단일(JSON) 문서에서 이루어지도록 권장합니다. 따라서 단일 고객 문서에는 고객 정보, 고객 주문, 고객 배송 정보, 고객 청구 정보가 포함될 수 있습니다. 단일 검색 인덱스를 사용하려면 검색하려는 모든 필드를 결합한 매우 큰 단일 인덱스를 만들어야 합니다. 고객 주소를 검색할 때 배송지 주소를 표시하고 싶지 않다는 문제가 있습니다. 배송 주문 ID를 검색할 때 반품된 주문 ID를 보고 싶지 않을 수 있습니다.
  2. MongoDB에서 스칼라에 여러 인덱스를 만들 수 있습니다. 텍스트 인덱스에 제한이 있는 이유는 무엇인가요?

MongoDB 텍스트 인덱스가 컬렉션당 하나의 인덱스로 제한되는 이유는 무엇인가요?  

    • 텍스트 인덱스의 수인가요? 검색 인덱스는 일반적으로 역 트리 데이터 구조. 하지만, 몽고DB는 다음을 구축하기로 결정했습니다. B-Tree 인덱스를 사용합니다. 이것은 문제가 되지 않을 것 같습니다.
    • 텍스트 인덱스의 크기인가요? 텍스트 인덱스는 텍스트에 토큰 배열을 생성하고 이를 인덱싱합니다. 즉, 배열 인덱스입니다. 배열 인덱스를 사용하면 그 크기가 기하급수적으로 커질 수 있습니다. 인덱스의 크기는 문서 수가 아니라 인덱스에 포함된 단어 수에 따라 선형적으로 증가합니다. 문제가 발생할 수 있습니다.
    • 최적화 프로그램에 문제가 있나요? 인덱스가 여러 개 있는 경우 최적화 도구가 쿼리에 적합한 인덱스를 선택해야 합니다. 하나의 텍스트 인덱스로 제한하면 쉽게 선택할 수 있습니다. 이것은 MongoDB 최적화 기술의 더 큰 문제의 증상입니다. 즉, 즉흥적인 결정을 내리기 때문에 이와 같은 제한이 발생합니다.

MongoDB의 쿼리 계획 언어는 다음과 같이 단순합니다. SQL 작업을 모방합니다.. MongoDB의 쿼리 최적화 도구가 이를 어떻게 처리하는지 살펴보겠습니다.

  1. 쿼리 재작성:  지원되지 않음. MongoDB의 쿼리는 찾기(), 저장(), 제거(), 업데이트() 메서드에서 단순합니다. 집계 파이프라인은 절차적이고 장황합니다. 이론적으로는 재작성이 가능하지만, 문서나 계획에는 쿼리 재작성을 나타내는 내용이 없습니다.
  2. 색인 선택: 지원. MongoDB의 최적화 도구는 쿼리의 각 부분에 적합한 인덱스를 선택하려고 시도하며 인덱스를 사용할 수 있거나 사용해야 합니다. 이에 대한 자세한 내용은 아래에서 확인하세요.
  3. 재주문에 참여하세요: 지원되지 않음. MongoDB의 $lookup은 쿼리가 절차적 접근 방식인 Unix 파이프라인처럼 작성되는 복잡한 집계 프레임워크의 일부입니다.  
  4. 조인 유형 선택: 지원되지 않음 유형 조인이 하나만 있기 때문입니다. MongoDB는 $lookup 연산자를 통해 왼쪽 외부 조인을 제한적으로 지원하므로 조인 조건에서 배열이 지원되지 않습니다. $lookup을 사용하는 경우 옵티마이저는 자동으로 기본 조인 알고리즘을 사용합니다. 수행되는 조인 유형에 대한 언급이 없습니다.  

기본적으로 MongoDB 쿼리 최적화는 실행 계획을 생성하기 전에 인덱스 선택만 수행합니다. 그러나 MongoDB의 쿼리 최적화는 규칙에 의해서도 아니고 통계에 의해서도 아닌 이상한 방식으로 인덱스를 선택하는 것 같습니다.  

  1. 하나 이상의 정규화된 인덱스에서 임의의 인덱스를 선택합니다.
  2. 상수, 선택성 및 추기경이 다르더라도 후속 쿼리가 쿼리 술어와 일치하는 경우 이 계획을 사용합니다.
  3. 그런 다음 런타임에 인덱스 스캔에서 100개 이상의 키가 반환되면(!) 각 대체 계획을 실행하여 어떤 계획이 먼저 키를 반환하는지 확인합니다. 어느 시점에서 병렬 실행을 중단하고 그 중 하나를 선택합니다. 또한 해당 계획을 계획 캐시에 있는 계획으로 대체합니다.

이것은 (x), (y), (x, y), (y, x)에 4개의 인덱스가 있는 단일 컬렉션입니다. 이제 이것을 보세요:

이 간단한 문서 구조에서도 쿼리에 x와 y에 대한 필터가 있음에도 불구하고 MongoDB는 (y)에 대한 인덱스를 선택합니다: ({x:{$gt:0}, y:99}).

이러한 모든 불확실성과 이로 인해 발생할 수 있는 성능 문제를 관리하기 위해 MongoDB는 쿼리 계획 캐시를 관리할 API 수특정 캐시 항목 플러시, 전체 플랜 캐시 플러시. 애플리케이션을 개발하는 대신 MongoDB 개발자 및 DBA는 계획 캐시를 관리해야 합니다. 개발자와 DBA는 다른 엔터프라이즈 데이터베이스의 계획 캐시를 관리할 필요가 없습니다.

원래 질문으로 돌아갑니다: MongoDB에서 여러 개의 텍스트 인덱스를 만들 수 없는 이유는 무엇인가요?

여러 인덱스를 구축하는 것은 단순히 허용하는 경우 문제가 되지 않습니다. 하지만 실제 문제 는 쿼리에 텍스트 술어를 지정하면 MongoDB 옵티마이저가 올바른 인덱스를 선택할 수 없다는 것입니다. 텍스트 술어에 대해 이러한 텍스트 인덱스의 유효성을 검사할 수 없습니다. MongoDB 최적화 도구는 자연스러운 논리나 논리적 프레임워크를 따르지 않습니다. 따라서 제한이 있습니다.

심지어 다칠 수도 있습니다!

Couchbase N1QL은 곧 출시될 릴리스에서 텍스트 인덱스를 N1QL에 추가했습니다. 자세한 내용은 다음에서 확인하세요. https://www.couchbase.com/blog/n1ql-and-search-how-to-leverage-fts-index-in-n1ql-query/. 사용자는 원하는 수의 텍스트 인덱스를 생성할 수 있으며, 최적화 도구는 적격(색인 가능한) 인덱스를 선택하여 이를 사용합니다. 또한 옵티마이저가 검색 술어를 이해하고 결정 로직에 계층화하기 때문에 조인, 포스트 인덱스 스캔 등의 검색을 지원합니다. 새로운 API나 관리해야 할 새로운 계획이 없습니다. 이것이 바로 Couchbase의 힘입니다!

리소스:
  1. 관계형 시스템의 쿼리 최적화에 대한 개요: https://web.stanford.edu/class/cs345d-01/rl/chaudhuri98.pdf
  2. Couchbase N1QL 쿼리 최적화에 대해 자세히 알아보기: https://dzone.com/articles/a-deep-dive-into-couchbase-n1ql-query-optimization
  3. https://docs.mongodb.com/manual/reference/method/js-plan-cache/
  4. https://docs.mongodb.com/manual/core/query-plans/
  5. https://docs.mongodb.com/manual/reference/method/js-plan-cache/

 

작성자

게시자 케샤브 머시

케샤브 머시는 Couchbase R&D의 부사장입니다. 이전에는 MapR, IBM, Informix, Sybase에서 근무했으며 데이터베이스 설계 및 개발 분야에서 20년 이상의 경력을 쌓았습니다. IBM Informix에서 SQL 및 NoSQL R&D 팀을 이끌었습니다. Couchbase에서 두 번의 President's Club 상을, IBM에서 두 번의 우수 기술 업적상을 수상했습니다. 인도 마이소르 대학교에서 컴퓨터 과학 및 공학 학사 학위를 받았으며, 10개의 미국 특허를 보유하고 있고 3개의 미국 특허를 출원 중입니다.

댓글 남기기