데이터베이스는 쿼리를 어떻게 이해하고 실행하나요?
표지 이미지
이 글은 Angela Ni가 번역했습니다.
Milvus의 벡터 쿼리는 부울 표현식에 기반한 스칼라 필터링을 통해 벡터를 검색하는 프로세스입니다. 스칼라 필터링을 통해 사용자는 데이터 속성에 특정 조건을 적용하여 쿼리 결과를 제한할 수 있습니다. 예를 들어, 사용자가 1990~2010년에 개봉한 영화 중 8.5점 이상인 영화를 쿼리할 경우, 해당 속성(개봉 연도 및 점수)이 조건을 충족하는 영화만 표시합니다.
이번 포스팅에서는 쿼리 표현식 입력부터 쿼리 계획 생성 및 쿼리 실행까지 Milvus에서 쿼리가 어떻게 완료되는지 살펴보겠습니다.
바로가기:
쿼리 표현식
Milvus에서 속성 필터링이 적용된 쿼리 표현식은 EBNF(확장 백커스-나우어 형식) 구문을 채택하고 있습니다. 아래 그림은 Milvus의 표현식 규칙입니다.
표현식 구문
논리 표현식은 이진 논리 연산자, 단항 논리 연산자, 논리 표현식, 단일 표현식의 조합을 사용하여 만들 수 있습니다. EBNF 구문 자체가 재귀적이기 때문에 논리 표현식은 조합의 결과이거나 더 큰 논리 표현식의 일부일 수 있습니다. 논리 표현식은 많은 하위 논리 표현식을 포함할 수 있습니다. Milvus에서도 동일한 규칙이 적용됩니다. 사용자가 여러 조건으로 결과의 속성을 필터링해야 하는 경우, 사용자는 다양한 논리 연산자와 표현식을 조합하여 자신만의 필터링 조건 집합을 만들 수 있습니다.
부울 표현식
위 이미지는 Milvus의 부울 표현식 규칙 중 일부를 보여줍니다. 표현식에 단항 논리 연산자를 추가할 수 있습니다. 현재 Milvus는 시스템에서 스칼라 필드 값이 계산 결과를 만족하지 않는 벡터를 가져와야 함을 나타내는 단항 논리 연산자 "not"만 지원합니다. 이진 논리 연산자에는 "and" 및 "or"가 포함됩니다. 단일 표현식에는 용어 표현식과 비교 표현식이 포함됩니다.
더하기, 빼기, 곱하기, 나누기와 같은 기본적인 산술 계산도 Milvus에서 쿼리 중에 지원됩니다. 다음 이미지는 연산의 우선 순위를 보여줍니다. 연산자는 내림차순으로 위에서 아래로 나열됩니다.
우선 순위
특정 영화에 대한 쿼리 표현식이 Milvus에서 어떻게 처리될까요?
Milvus에 많은 필름 데이터가 저장되어 있고 사용자가 특정 필름을 쿼리하고자 한다고 가정해 보겠습니다. 예를 들어 Milvus에 저장된 각 영화 데이터에는 영화 ID, 개봉 연도, 영화 유형, 점수, 포스터의 다섯 가지 필드가 있습니다. 이 예에서 영화 ID와 개봉 연도의 데이터 유형은 int64이고, 영화 점수는 부동 소수점 데이터입니다. 또한 영화 포스터는 부동 소수점 벡터 형식으로, 영화 유형은 문자열 데이터 형식으로 저장됩니다. 특히 문자열 데이터 유형에 대한 지원은 Milvus 2.1의 새로운 기능입니다.
예를 들어 사용자가 8.5점보다 높은 점수를 받은 영화를 쿼리하고자 한다고 가정해 보겠습니다. 또한 영화가 2000년 이전 10년에서 2000년 이후 10년 사이에 개봉했거나 영화 유형이 코미디 또는 액션 영화여야 하는 경우, 사용자는 다음과 같은 술어 표현식을 입력해야 합니다: score > 8.5 && (2000 - 10 < release_year < 2000 + 10 || type in [comedy,action])
.
쿼리 표현식을 받으면 시스템은 다음 우선순위에 따라 실행합니다:
- 8.5점보다 높은 점수를 받은 영화를 쿼리합니다. 쿼리 결과를 "result1"이라고 합니다.
- 2000 - 10을 계산하여 "result2"(1990)를 얻습니다.
- 2000 + 10을 계산하여 "result3"(2010)을 얻습니다.
release_year
값이 "result2"보다 크고 "result3"보다 작은 영화에 대해 쿼리합니다. 즉, 시스템에서 1990년부터 2010년 사이에 개봉한 영화를 쿼리해야 합니다. 쿼리 결과를 "result4"라고 합니다.- 코미디 또는 액션 영화인 영화를 쿼리합니다. 쿼리 결과를 "result5"라고 합니다.
- "result4"와 "result5"를 결합하여 1990년부터 2010년 사이에 개봉했거나 코미디 또는 액션 영화 카테고리에 속하는 영화를 얻습니다. 결과를 "result6"이라고 합니다.
- "result1"과 "result6"의 공통 부분을 취하여 모든 조건을 만족하는 최종 결과를 얻습니다.
영화 예제
AST 생성 계획
Milvus는 AST(추상 구문 트리) 생성을 위해 오픈 소스 도구인 ANTLR (ANother Tool for Language Recognition)을 활용합니다. ANTLR은 구조 텍스트 또는 바이너리 파일을 읽고, 처리하고, 실행하거나 번역하기 위한 강력한 파서 생성기입니다. 보다 구체적으로, ANTLR은 사전 정의된 구문 또는 규칙을 기반으로 구문 분석 트리를 구축하고 워킹하기 위한 구문 분석기를 생성할 수 있습니다. 다음 이미지는 입력 표현식이 "SP=100;"인 예제입니다. ANTLR에 내장된 언어 인식 기능인 LEXER는 입력 표현식에 대해 "SP", "=", "100", ";" 등 네 개의 토큰을 생성합니다. 그런 다음 이 도구는 4개의 토큰을 추가로 파싱하여 해당 파싱 트리를 생성합니다.
구문 분석 트리
워커 메커니즘은 ANTLR 도구에서 매우 중요한 부분입니다. 워커 메커니즘은 모든 구문 분석 트리를 탐색하여 각 노드가 구문 규칙을 준수하는지 검사하거나 특정 민감한 단어를 감지하도록 설계되었습니다. 관련 API 중 일부는 아래 이미지에 나열되어 있습니다. ANTLR은 루트 노드에서 시작하여 각 하위 노드를 거쳐 맨 아래까지 내려가기 때문에 구문 분석 트리를 걷는 순서를 구분할 필요가 없습니다.
구문 분석 트리 워커
Milvus는 ANTLR과 유사한 방식으로 쿼리용 PlanAST를 생성합니다. 그러나 ANTLR을 사용하려면 다소 복잡한 구문 규칙을 재정의해야 합니다. 따라서 Milvus는 가장 널리 사용되는 규칙 중 하나인 부울 표현식 규칙을 채택하고, 쿼리 표현식의 구문을 쿼리하고 구문 분석하기 위해 GitHub에서 오픈 소스된 Expr 패키지에 의존합니다.
속성 필터링이 있는 쿼리 중에 Milvus는 쿼리 식을 수신하면 Expr에서 제공하는 구문 분석 방법인 앤트 파서를 사용하여 원시 미해결 계획 트리를 생성합니다. 기본 계획 트리는 단순한 이진 트리입니다. 그런 다음 이 계획 트리는 Expr과 Milvus에 내장된 최적화 도구에 의해 미세 조정됩니다. Milvus의 최적화 도구는 앞서 언급한 워커 메커니즘과 매우 유사합니다. Expr에서 제공하는 플랜 트리 최적화 기능은 매우 정교하기 때문에 Milvus에 내장된 옵티마이저의 부담이 상당 부분 완화됩니다. 최종적으로 분석기는 최적화된 플랜 트리를 재귀적인 방식으로 분석하여 프로토콜 버퍼 (protobuf) 구조의 플랜 AST를 생성합니다.
계획 AST 워크플로우
쿼리 실행
쿼리 실행은 이전 단계에서 생성된 계획 AST의 실행을 근간으로 합니다.
Milvus에서 plan AST는 프로토 구조로 정의됩니다. 아래 이미지는 프로토 구조의 메시지입니다. 표현식은 6가지 유형이 있으며, 이 중 이진 표현식과 단항 표현식은 이진 논리 표현식과 단항 논리 표현식을 추가로 가질 수 있습니다.
protobuf1
protobuf2
아래 이미지는 쿼리 표현식의 UML 이미지입니다. 각 표현식의 기본 클래스와 파생 클래스를 보여줍니다. 각 클래스에는 방문자 매개변수를 받아들이는 메서드가 있습니다. 이것은 일반적인 방문자 디자인 패턴입니다. 이 패턴의 가장 큰 장점은 사용자가 기본 표현식에 아무 작업도 하지 않고 패턴의 메서드 중 하나에 직접 접근하여 특정 쿼리 표현식 클래스 및 관련 요소를 수정할 수 있다는 점입니다.
UML
계획 AST를 실행할 때 Milvus는 먼저 프로토 타입의 계획 노드를 받습니다. 그런 다음 내부 C++ 프로토 파서를 통해 세그코어 타입의 플랜 노드를 얻습니다. 두 가지 유형의 플랜 노드를 얻으면 Milvus는 일련의 클래스 액세스를 수락한 다음 플랜 노드의 내부 구조에서 수정 및 실행합니다. 마지막으로 Milvus는 모든 실행 계획 노드를 검색하여 필터링된 결과를 얻습니다. 최종 결과는 비트마스크 형식으로 출력됩니다. 비트마스크는 비트 숫자("0"과 "1")의 배열입니다. 필터 조건을 충족하는 데이터는 비트마스크에서 "1"로 표시되고, 조건을 충족하지 않는 데이터는 비트마스크에서 "0"으로 표시됩니다.
워크플로 실행
심층 분석 시리즈 소개
Milvus 2.0의 공식 출시와 함께 Milvus 아키텍처와 소스 코드에 대한 심층적인 해석을 제공하기 위해 Milvus 딥 다이브 블로그 시리즈를 기획했습니다. 이 블로그 시리즈에서 다루는 주제는 다음과 같습니다:
- 쿼리 표현식
- AST 생성 계획
- 쿼리 실행
- 심층 분석 시리즈 소개
On This Page
Try Managed Milvus for Free
Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.
Get StartedLike the article? Spread the word