카우치베이스 애널리틱스

애널리틱스 쿼리 최적화 - Listify를 이해해 봅시다.

카우치베이스 애널리틱스는 효율적인 병렬 처리를 활용하여 애드혹 쿼리를 지원하도록 설계되었습니다. 이는 한 쿼리의 결과로 인해 또 다른 쿼리에서 답을 찾아야 할 때 특히 유용합니다. (즉, 분석가에게는 항상 그렇습니다!) 다른 데이터 플랫폼과 마찬가지로, 이러한 보조 쿼리는 때때로 첫 번째 쿼리와 상당히 다른 실행 시간을 초래할 수 있습니다. 최근에 쿼리를 조금 변경한 후 성능이 눈에 띄게 저하된 고객과 함께 작업한 적이 있습니다. 문제를 분리하고 해결하기 위해 진행한 프로세스는 다음과 같습니다.

데이터

항상 그렇듯이 쿼리를 이해하기 위한 첫 번째 단계는 기초 데이터에 익숙해지는 것입니다. 이 경우 데이터는 JSON 문서로 구성되며, 각 문서는 서비스에 대한 클라이언트 요금에 대한 설명입니다. 각 세션에 대한 요금은 배열 안에 포함되어 있습니다:

데이터 모델 설계에 대한 몇 가지 참고 사항입니다:

  • 그들은 필드 이름을 설명할 수 있을 만큼 길지만 공간을 절약할 수 있을 만큼 짧게 지정하는 현명함을 발휘했습니다. 배열 내의 필드명은 '수량', 'revenueCode', '서비스', '금액', '서비스 날짜'로 쉽게 작성할 수 있었습니다. 그러나 1억 개의 인스턴스에 걸쳐 이렇게 하면 압축하기 전에 3.73GB의 공간이 추가로 필요했을 것입니다.
  • 밀리초가 없는 에포크 날짜를 사용했습니다. 이러한 날짜가 ISO 8601 형식("2020-07- 24T18:17:49" 또는 밀리초 "2020-07-24T18:17:49.000")으로 저장되면 저장 공간이 두 배로 늘어납니다.

초기 쿼리

초기 쿼리는 각 수익 코드 범주 내에서 가장 높은 수익 고객/서비스 조합을 검색하도록 설계되었습니다:

쿼리 디자인에 대한 몇 가지 참고 사항입니다:

  • 배열 콘텐츠는 "unnest" 동사로 액세스합니다. 이렇게 하면 값을 집계하여 평활화된 레코드로 반환할 수 있습니다.
  • 최신 서비스 날짜는 millis_to_str() 함수를 통해 에포크에서 사람이 읽을 수 있는 날짜로 변환됩니다.
  • 윈도우 함수 "rank() over partition"은 각 수익 코드 내에서 상위 값만 반환하는 효율적인 수단으로 외부 쿼리의 where 절에 사용됩니다.
  • round() 함수는 장식용이지만, 일반적으로 페니가 중요하지 않은 보고서에서 사용됩니다.

슬로우다운

볼륨 할인 계산(서비스 누적 수량이 10개 이상일 때 20% 할인)이 추가되었을 때 문제가 발생했습니다. 이 새로운 쿼리는 실행 시간이 6배나 더 오래 걸렸습니다!

이 원인을 어떻게 추적할 수 있나요?

설명하기

Analytics 쿼리 콘솔에서는 '계획' 버튼을 클릭하기만 하면 모든 쿼리의 실행 계획을 쉽게 검사할 수 있습니다. 아래 그림 (1)은 이 쿼리에 대한 쿼리 계획을 보여줍니다. 다이어그램의 규모가 작아도 걱정하지 마세요. 컨트롤을 사용하여 확장 및 축소할 수 있습니다. 각 개별 단계를 클릭하여 자세한 정보를 볼 수도 있습니다.

Figure 1

그림 1

원하는 경우 '계획 텍스트' 버튼을 클릭하여 계획을 설명하는 JSON 문서를 생성할 수도 있습니다:

 

쿼리가 복잡해지면 중첩이 매우 깊어지고 읽기가 다소 어려워질 수 있습니다. 엔지니어들이 자주 사용하는 트릭은 쿼리 앞에 '설명 텍스트' 명령을 추가하는 것입니다:

여기에는 괄호 없이 계획에 대한 자세한 설명이 제공됩니다:

이것이 단서를 찾는 데 사용할 것입니다.

목록 만들기

필드를 정의하는 CASE 문을 추가했을 때 속도 저하가 발생했다고 확신하므로 케이스 로직을 검색하는 것부터 시작해 보겠습니다. 33번째 줄에서 찾을 수 있습니다:

다음 줄의 논리를 따라가다 보면 실행 계획이 분할된 방식으로 변수를 계속 할당하고 교환하는 것을 볼 수 있습니다. 그러나 44번째 줄에는 다음과 같은 내용이 표시됩니다:

쿼리 성능이나 메모리 소비가 우려되는 경우, "listify" 함수는 위험 신호가 될 수 있습니다. (한 엔지니어는 농담 삼아 "악의 함수"라고 부르기도 합니다.) 특히 배열 집계의 내부 변환에 사용되지만 실행 계획에서 최후의 수단으로 사용할 수도 있습니다. 이 예제에서는 $$117 변수가 이 리스트파이 프로세스의 결과물임을 알 수 있습니다. 위의 스위치 케이스에서 볼 수 있는 이 $$117은 쿼리의 sum(c.amt) 객체와 연관되어 있습니다. 따라서 합계 계산을 내부 스위치 케이스 밖으로 이동하여 LET의 일부로 만들어 보겠습니다:

이 작업을 완료하고 explain plan을 다시 살펴본 결과 길이가 절반으로 줄었고 실행 프로세스에 더 이상 listify 함수가 포함되지 않는 것을 확인할 수 있습니다. 그러면 쿼리를 실행하면 훨씬 더 나은 성능을 보여야 하며 실제로도 그렇습니다. 문제가 해결되었습니다!

마지막으로 한 가지 참고사항: 엔지니어들은 항상 쿼리 최적화 도구를 개선할 방법을 찾고 있습니다. 쿼리 중 하나를 최적화하는 과정에서 설명 텍스트에서 불량 'listify' 함수(이미 드물지만 점점 더 드물어지고 있음)를 발견한 경우, support.couchbase.com에서 지원 티켓을 열고 설명 계획을 업로드하여 엔지니어가 살펴볼 수 있도록 해 주세요. 실제로 위에서 언급한 고객과의 작업 결과로 이 특정 예제(집계 함수와 함께 사용되는 스위치 케이스)는 6.6 릴리스부터 최적화 프로그램에 의해 자동으로 재작성됩니다.

문서 및 리소스

Couchbase 문서 사이트에는 분석 언어용 N1QL 참조에 대한 링크가 포함되어 있습니다: https://docs.couchbase.com/server/current/analytics/introduction.html. 또한 여기에서 언어에 대한 튜토리얼과 Don Chamberlin(SQL 언어의 공동 발명가)의 책에 대한 링크를 찾을 수 있습니다: https://www.couchbase.com/sql-plus-plus-for-sql-users.

 

이 게시물을 꼼꼼하게 검토해 주신 Dmitry Lychagin과 Mike Carey에게 깊은 감사를 드립니다.

 

이 문서 공유하기
받은 편지함에서 카우치베이스 블로그 업데이트 받기
이 필드는 필수 입력 사항입니다.

작성자

게시자 Peter Reale, 선임 솔루션 엔지니어, Couchbase

Peter Reale은 1984년부터 데이터 비즈니스에 종사해 온 Couchbase의 수석 솔루션 엔지니어입니다. 현재 로스앤젤레스에 거주하고 있습니다.

댓글 남기기

카우치베이스 카펠라를 시작할 준비가 되셨나요?

구축 시작

개발자 포털에서 NoSQL을 살펴보고, 리소스를 찾아보고, 튜토리얼을 시작하세요.

카펠라 무료 사용

클릭 몇 번으로 Couchbase를 직접 체험해 보세요. Capella DBaaS는 가장 쉽고 빠르게 시작할 수 있는 방법입니다.

연락하기

카우치베이스 제품에 대해 자세히 알고 싶으신가요? 저희가 도와드리겠습니다.