중요합니다
이 기능은 프리뷰 상태입니다.
Cosmos DB는 스키마 또는 인덱스 관리를 처리하지 않고도 애플리케이션을 반복할 수 있는 스키마에 구애받지 않는 데이터베이스입니다. Microsoft Fabric의 Cosmos DB 내 인덱싱은 데이터가 어떻게 진화하든 빠르고 유연한 쿼리 성능을 제공하도록 설계되었습니다. 패브릭의 Cosmos DB에서 모든 컨테이너에는 컨테이너의 항목을 인덱싱하는 방법을 지시하는 인덱싱 정책이 있습니다. 새로 만든 컨테이너에 대한 기본 인덱싱 정책은 모든 항목의 모든 속성을 인덱싱하고 모든 문자열 또는 숫자에 대해 범위 인덱스를 적용합니다. 이 기본 구성을 사용하면 인덱싱 및 인덱스 관리를 미리 생각하지 않고도 좋은 쿼리 성능을 얻을 수 있습니다.
사용자 요구 사항에 맞게 이 자동 동작을 재정의할 수 있는 상황이 있습니다. 인덱싱 모드를 설정하여 컨테이너의 인덱싱 정책을 사용자 지정하고, 속성 경로를 포함하거나 제외할 수 있습니다.
인덱싱 모드
Cosmos DB는 다음 두 가지 인덱싱 모드를 지원합니다.
일관성: 항목을 만들거나 업데이트하거나 삭제할 때 인덱스가 동기적으로 업데이트됩니다.
없음: 컨테이너에서 인덱싱을 사용하지 않습니다. 이 모드는 보조 인덱스 없이 컨테이너를 순수 키-값 저장소로 사용하는 경우에 일반적으로 사용됩니다. 이를 사용하여 대량 작업의 성능을 향상시킬 수도 있습니다. 대량 작업이 완료되면 인덱스 모드를 설정하여
Consistent
완료될 때까지 SDK의IndexTransformationProgress
기능을 사용하여 모니터링할 수 있습니다.
비고
Cosmos DB는 지연 인덱싱 모드도 지원합니다. 지연 인덱싱은 엔진이 다른 작업을 수행하지 않을 때 낮은 우선 순위 수준에서 인덱스에 대한 업데이트를 수행합니다. 이 동작은 일관되지 않거나 불완전한 쿼리 결과를 초래할 수 있습니다. Cosmos DB 컨테이너를 쿼리하려는 경우 지연 인덱싱을 선택해서는 안 됩니다. 새 컨테이너는 지연 인덱싱을 선택할 수 없습니다.
인덱스 크기
Cosmos DB에서 사용된 총 스토리지는 데이터 크기와 인덱스 크기의 조합입니다. 인덱스 크기의 몇 가지 기능은 다음과 같습니다.
인덱스 크기는 인덱싱 정책에 따라 달라집니다. 모든 속성이 인덱싱되는 경우 인덱스 크기가 데이터 크기보다 클 수 있습니다.
데이터가 삭제되면 인덱스는 거의 지속적으로 압축됩니다. 그러나 작은 데이터 삭제의 경우 인덱스 크기의 감소가 즉시 보이지 않을 수 있습니다.
실제 파티션이 분할되면 인덱스 크기가 일시적으로 늘어날 수 있습니다. 파티션 분할이 완료되면 인덱스 공간이 해제됩니다.
시스템 속성
id
은_ts
컨테이너의 인덱싱 모드가 일관성일 때 항상 인덱싱됩니다.시스템 속성
id
이며_ts
컨테이너 정책에 대한 인덱싱된 경로 설명에 포함되지 않습니다. 이러한 시스템 속성은 항상 기본적으로 인덱싱되며 이 동작을 사용하지 않도록 설정할 수 없으므로 이 제외는 기본적으로 사용됩니다.
비고
파티션 키(또한 /id
인 경우가 아니면)는 인덱싱되지 않으며 인덱스에 포함되어야 합니다.
속성 경로 포함 및 제외
사용자 지정 인덱싱 정책은 인덱싱에 명시적으로 포함되거나 인덱싱에서 명시적으로 제외되는 속성 경로를 지정할 수 있습니다. 인덱싱되는 경로 수를 최적화하면 쓰기 작업의 대기 시간 및 RU 요금을 크게 줄일 수 있습니다.
이 JSON 항목을 다시 고려합니다.
{
"locations": [
{ "country": "Germany", "city": "Berlin" },
{ "country": "France", "city": "Paris" }
],
"headquarters": { "country": "Belgium", "employees": 250 },
"exports": [
{ "city": "Moscow" },
{ "city": "Athens" }
]
}
이 인덱싱 정책은 다음과 같은 인덱싱 경로를 생성합니다.
경로 | 가치 |
---|---|
/locations/0/country |
"Germany" |
/locations/0/city |
"Berlin" |
/locations/1/country |
"France" |
/locations/1/city |
"Paris" |
/headquarters/country |
"Belgium" |
/headquarters/employees |
250 |
/exports/0/city |
"Moscow" |
/exports/1/city |
"Athens" |
이러한 경로는 다음 추가를 사용하여 정의됩니다.
스칼라 값(문자열 또는 숫자)으로 연결되는 경로는
/?
로 끝납니다배열의 요소는
/[]
표기법으로 함께 참조됩니다(/0
,/1
등 대신)./*
와일드카드를 사용하여 노드 아래의 어떤 요소도 일치시킬 수 있습니다
예제 항목에 대한 기준 인덱싱 정책에는 다음과 같은 최적화가 포함될 수 있습니다.
headquarters
의employees
경로는/headquarters/employees/?
입니다locations
의country
경로는/locations/[]/country/?
입니다headquarters
아래 있는 모든 항목의 경로는/headquarters/*
입니다
예를 들어 /headquarters/employees/?
경로를 포함할 수 있습니다. 이 경로는 employees
속성을 인덱싱하는 것을 보장하지만 이 속성 내에서 중첩된 추가 JSON은 인덱싱하지 않습니다.
포함/제외 전략
모든 인덱싱 정책은 루트 경로 /*
를 포함된 경로 또는 제외된 경로로 포함해야 합니다.
인덱싱할 필요가 없는 경로를 선택적으로 제외하려면 루트 경로를 포함합니다. Cosmos DB에서 모델에 추가할 수 있는 새 속성을 사전에 인덱싱할 수 있으므로 이 방법을 사용하는 것이 좋습니다.
인덱싱해야 하는 경로를 선택적으로 포함하려면 루트 경로를 제외합니다. 파티션 키 속성 경로는 기본적으로 제외된 전략으로 인덱싱되지 않으며 필요한 경우 명시적으로 포함해야 합니다.
영숫자 문자와 _(밑줄)을 포함하는 정규 문자가 있는 경로에서는 큰따옴표 앞뒤의 경로 문자열을 이스케이프할 필요가 없습니다(예: "/path/?"). 다른 특수 문자를 포함하는 경로의 경우 큰따옴표 앞뒤의 경로 문자열을 이스케이프해야 합니다(예: "/"path-abc"/?"). 경로에 특수 문자가 필요한 경우 안전을 위해 모든 경로를 이스케이프할 수 있습니다. 기능적으로 모든 경로를 이스케이프하거나 특수 문자를 포함하는 경로만 이스케이프해도 아무런 차이가 없습니다.
시스템 속성
_etag
는 인덱싱에 포함되는 경로에 etag를 추가하지 않는 한 기본적으로 인덱싱에서 제외됩니다.인덱싱 모드가 일관성으로 설정된 경우 시스템 속성
id
및_ts
가 자동으로 인덱싱됩니다.항목에 명시적으로 인덱싱된 경로가 없는 경우 경로가 정의되지 않았음을 나타내는 값이 인덱스에 추가됩니다.
명시적으로 포함된 모든 경로에는 지정된 항목에 대해 경로가 정의되지 않은 경우에도 컨테이너의 각 항목에 대한 인덱스에 값이 추가됩니다.
자세한 내용은 샘플 인덱싱 정책을 참조하세요.
포함/제외 우선 순위
포함된 경로와 제외된 경로에 충돌이 있는 경우 보다 정확한 경로가 우선 적용됩니다.
다음 예제를 고려하세요.
포함된 경로:
/food/ingredients/nutrition/*
제외된 경로:
/food/ingredients/*
이 경우 포함된 경로가 보다 정확하기 때문에 제외된 경로보다 우선 적용됩니다. 이러한 경로에 따라 경로에 있거나 /food/ingredients
경로 내에 중첩된 모든 데이터는 인덱스에서 제외됩니다. 포함된 경로인 /food/ingredients/nutrition/*
내의 데이터는 예외이며 인덱싱됩니다.
다음은 Cosmos DB에서 포함 및 제외된 경로 우선 순위에 대한 몇 가지 규칙입니다.
더 깊은 경로는 더 좁은 경로보다 더 정확합니다. 예를 들어
/a/b/?
는/a/?
보다 더 정확합니다./?
가/*
보다 더 정확합니다./a/?
가/a/*
보다 더 정확하기 때문에/a/?
가 우선합니다.경로
/*
는 포함된 경로 또는 제외된 경로여야 합니다.
전체 텍스트 인덱스
전체 텍스트 인덱스를 사용하면 인덱스를 사용하여 전체 텍스트 검색 및 채점을 효율적으로 수행할 수 있습니다. 인덱싱 정책에서 전체 텍스트 경로 정의는 인덱싱할 모든 텍스트 경로가 포함된 인덱싱 정책의 섹션을 포함하여 fullTextIndexes
쉽게 수행할 수 있습니다. 다음은 그 예입니다.
{
"indexingMode": "consistent",
"automatic": true,
"includedPaths": [
{
"path": "/*"
}
],
"excludedPaths": [
{
"path": "/\"_etag\"/?"
},
],
"fullTextIndexes": [
{
"path": "/text"
}
]
}
중요합니다
전체 텍스트 인덱싱 정책은 컨테이너의 전체 텍스트 정책에 정의된 경로에 있어야 합니다. 자세한 내용은 전체 텍스트 검색을 참조하세요.
벡터 인덱스
벡터 인덱스는 VECTORDISTANCE
시스템 함수를 사용하여 벡터 검색을 수행할 때 효율성을 높입니다. 벡터 검색은 벡터 인덱스를 적용할 때 대기 시간이 짧고 처리량이 높으며 RU(요청 단위) 사용량이 줄어듭니다. 다음 형식의 벡터 인덱스 정책을 지정할 수 있습니다.
유형 | 설명 | 최대 크기 |
---|---|---|
flat |
다른 인덱싱된 속성과 동일한 인덱스에 벡터를 저장합니다. | 505 |
quantizedFlat |
인덱스에 저장하기 전에 벡터를 양자화(압축)합니다. 이 형식은 적은 양의 정확도로 대기 시간 및 처리량을 향상시킬 수 있습니다. | 4096 |
diskANN |
DiskANN을 기반으로 빠르고 효율적인 근사 검색을 위한 인덱스를 만듭니다. | 4096 |
중요합니다
벡터 정책 및 벡터 인덱스는 만든 후에 변경할 수 없습니다. 변경하려면 새 컬렉션을 만듭니다.
주의할 사항:
및
quantizedFlat
인덱스 형식은flat
Cosmos DB의 인덱스를 사용하여 벡터 검색 중에 각 벡터를 저장하고 읽습니다. 인덱스를 사용한flat
벡터 검색은 무차별 대입 검색이며 100%의 정확도 또는 재현율을 제공합니다. 이 정확도는 검색이 항상 데이터 세트에서 가장 유사한 벡터를 찾는다는 것을 의미합니다. 그러나 인덱스는flat
최대505
차원의 벡터를 지원합니다.quantizedFlat
인덱스는 인덱스에 양자화된(압축된) 벡터를 저장합니다.quantizedFlat
인덱스를 사용한 벡터 검색도 무차별 검색이지만 벡터가 인덱스에 추가되기 전에 양자화되므로 정확도가 100%보다 약간 낮을 수 있습니다. 그러나quantized flat
을 사용한 벡터 검색은flat
인덱스의 벡터 검색보다 대기 시간이 짧고 처리량이 높으며 RU 비용이 낮아야 합니다. 이 형식은 쿼리 필터를 사용하여 벡터 검색 범위를 비교적 작은 벡터 집합으로 좁히는 시나리오에 적합한 옵션입니다. 이 시나리오에서는 높은 정확도가 필요합니다.diskANN
인덱스는 Microsoft Research에서 개발한 고성능 벡터 인덱스 알고리즘 도구 모음인 DiskANN을 적용하여 벡터에 대해 특별히 정의된 별도의 인덱스입니다. DiskANN 인덱스는 높은 정확도를 유지하면서 가장 낮은 대기 시간, 가장 높은 처리량, 가장 낮은 RU 비용 쿼리를 제공할 수 있습니다. 그러나 DiskANN은 ANN(Approximous Nearest Neighbors) 인덱스이므로 정확도가quantizedFlat
또는flat
보다 낮을 수 있습니다.diskANN
및quantizedFlat
인덱스는 모든 근사한 인접 항목 벡터 인덱스에 적용되는 대기 시간 장차와 정확도를 조정하는 데 사용할 수 있는 선택적 인덱스 빌드 매개 변수를 사용할 수 있습니다.
quantizationByteSize
: 제품 정량화의 크기(바이트)를 설정합니다. (Min=1
,Default=dynamic
(시스템 결정),Max=512
). 이 크기를 크게 설정하면 더 높은 RU 비용과 더 높은 대기 시간을 희생하여 정확도 벡터 검색이 높아질 수 있습니다. 이 절충은quantizedFlat
와DiskANN
인덱스 형식 모두에 적용됩니다.-
indexingSearchListSize
: 인덱스 빌드 생성 중에 검색할 벡터 수를 설정합니다. Min=10, Default=100, Max=500. 이 크기를 더 크게 설정하면 인덱스 빌드 시간이 길고 벡터 수집 대기 시간이 길어질수록 정확도 벡터 검색이 높아질 수 있습니다. 이 특성은 인덱스에DiskANN
만 적용됩니다.
-
다음은 벡터 인덱스를 사용한 인덱싱 정책의 예입니다.
{
"indexingMode": "consistent",
"automatic": true,
"includedPaths": [
{
"path": "/*"
}
],
"excludedPaths": [
{
"path": "/_etag/?",
},
{
"path": "/vector/*"
}
],
"vectorIndexes": [
{
"path": "/vector",
"type": "diskANN"
}
]
}
중요합니다
삽입에 최적화된 성능을 보장하려면 excludedPaths
인덱싱 정책 섹션에 벡터 경로를 추가해야 합니다. 벡터 경로를 excludedPaths
추가하지 않으면 벡터 삽입에 대한 RU 요금 및 대기 시간이 높아질 수 있습니다.
벡터 인덱싱 정책도 컨테이너의 벡터 정책에 정의된 경로에 있어야 합니다. 자세한 내용은 벡터 정책을 참조하세요.
공간 인덱스
인덱싱 정책에 공간 경로를 정의하는 경우 해당 경로에 적용해야 하는 인덱스 type
을 정의해야 합니다.
공간 인덱스에 사용할 수 있는 형식은 다음과 같습니다.
포인트
다각형
멀티폴리곤
라인스트링
기본적으로 Cosmos DB는 공간 인덱스를 만들지 않습니다. 공간 SQL 기본 제공 함수를 사용하려면 필요한 속성에 공간 인덱스를 만듭니다. 자세한 내용은 공간 인덱스를 참조하세요.
튜플 인덱스
튜플 인덱스는 배열 요소 내의 여러 필드에 대해 필터링을 수행할 때 유용합니다. 튜플 인덱스는 튜플 지정자를 []
사용하여 인덱싱 정책의 includedPaths 섹션에 정의됩니다.
비고
포함된 경로나 제외된 경로와 달리 /*
와일드카드를 사용하여 경로를 만들 수 없습니다. 모든 튜플 경로는 /?
로 끝나야 합니다. 튜플 경로의 튜플이 항목에 없는 경우 튜플이 정의되지 않았음을 나타내기 위해 값이 인덱스로 추가됩니다.
배열 튜플 경로는 includedPaths
섹션에서 다음 표기법을 사용하여 정의됩니다. <path prefix>/[]/{<tuple 1>, <tuple 2>, …, <tuple n>}/?
배열 튜플에 대해 다음과 같은 중요한 규칙을 고려합니다.
튜플의 각 부분은 쉼표로 구분됩니다.
첫 번째 부분인 경로 접두사는 튜플 간에 공통적인 경로입니다. 루트에서 배열로의 경로입니다. 이 예제에서는 다음과 같습니다
/events
.첫 번째 부분 이후 튜플에는 배열 와일드카드 지정자가
[]
포함되어야 합니다. 모든 배열 튜플 경로에는 튜플 지정자 앞에 배열 와일드카드 지정자가{}
있어야 합니다.다음 부분에서는 튜플 지정자를 사용하여 튜플을 지정합니다
{}
.튜플은 몇 가지 예외를 제외하고 다른 인덱스 경로와 동일한 경로 사양을 사용해야 합니다.
튜플은 선행
/
으로 시작해서는 안 됩니다.튜플에는 배열 와일드카드가 없어야 합니다.
튜플은
?
또는*
로 끝나서는 안 됩니다.?
는 튜플 경로의 마지막 세그먼트이며 튜플 지정자 세그먼트 바로 다음에 지정해야 합니다.
예를 들어 이 사양은 유효한 튜플 경로입니다. /events/[]/{name, category}/?
다음은 배열 튜플 경로의 몇 가지 유효한 예입니다.
[
{ "path": "/events/[]/{name/first, name/last}/?" },
{ "path": "/events/[]/{name/first, category}/?" },
{ "path": "/events/[]/{name/first, category/subcategory}/?" },
{ "path": "/events/[]/{name/[1]/first, category}/?" },
{ "path": "/events/[]/{[1], [3]}/?" },
{ "path": "/city/[1]/events/[]/{name, category}/?" }
]
다음은 설명이 포함된 잘못된 배열 튜플 경로의 몇 가지 예입니다.
잘못된 경로 | 설명 |
---|---|
/events/[]/{name/[]/first, category}/? |
튜플 중 하나에 배열 와일드카드가 있습니다. |
/events/[]/{name, category}/* |
배열 튜플 경로의 마지막 세그먼트는 ? 이어야 하며 * 이 아닙니다. |
/events/[]/{{name, first},category}/? |
튜플 지정자가 중첩됨 |
/events/{name, category}/? |
배열 와일드카드가 튜플 지정자 앞에 없습니다. |
/events/[]/{/name,/category}/? |
튜플은 특정 요소 / 로 시작해야 합니다. |
/events/[]/{name/?,category/?}/? |
튜플은 ? 로 끝나야 합니다. |
/city/[]/events/[]/{name, category}/? |
두 개의 배열 와일드카드를 포함하는 경로 접두사 |
복합 인덱스
속성이 두 개 이상인 ORDER BY
절이 있는 쿼리에는 복합 인덱스가 필요합니다. 복합 인덱스를 정의하여 여러 같음 및 범위 쿼리의 성능을 향상시킬 수도 있습니다. 기본적으로 복합 인덱스는 정의되지 않으므로 필요에 따라 복합 인덱스를 추가해야 합니다.
복합 인덱스 경로에서는 /*
와일드카드를 사용할 수 없습니다. 각 복합 경로는 /?
자동으로 종료되므로 추가할 필요가 없습니다. 복합 경로는 복합 인덱스에 포함된 유일한 값인 스칼라 값을 가리킵니다. 복합 인덱스 경로가 항목에 없거나 비칼라 값을 가리키는 경우 Cosmos DB는 인덱스에 값을 추가하여 경로가 정의되지 않음을 표시합니다.
복합 인덱스를 정의할 때 다음 두 구성 요소를 지정합니다.
복합 인덱스의 사용 방식에 영향을 주는 특정 순서로 정의된 두 개 이상의 속성 경로입니다.
오름차순 또는 내림차순으로 정의된 순서입니다.
복합 인덱스를 추가하면 쿼리는 새 복합 인덱스 추가가 완료될 때까지 기존 범위 인덱스를 활용합니다. 따라서 복합 인덱스를 추가하는 경우 성능 향상이 즉시 관찰되지 않을 수 있습니다.
팁 (조언)
SDK(소프트웨어 개발 키트) 중 하나를 사용하여 인덱스 변환의 진행률을 추적할 수 있습니다.
여러 속성에 대한 ORDER BY
쿼리:
다음 고려 사항은 둘 이상의 속성이 있는 절이 있는 ORDER BY
쿼리에 복합 인덱스를 사용할 때 사용됩니다.
복합 인덱스 경로가
ORDER BY
절의 속성 시퀀스와 일치하지 않는 경우 복합 인덱스가 쿼리를 지원할 수 없습니다.복합 인덱스 경로의 순서(오름차순 또는 내림차순)는
order
절의ORDER BY
와도 일치해야 합니다.복합 인덱스는 모든 경로에서 순서가 반대인
ORDER BY
절도 지원합니다.
복합 인덱스가 속성 name, age, _ts에서 정의되는 다음 예를 살펴보세요.
복합 인덱스 | 샘플 ORDER BY 쿼리 |
복합 인덱스가 지원합니까? |
---|---|---|
(name ASC, age ASC) |
SELECT * FROM c ORDER BY c.name ASC, c.age asc |
Yes |
(name ASC, age ASC) |
SELECT * FROM c ORDER BY c.age ASC, c.name asc |
No |
(name ASC, age ASC) |
SELECT * FROM c ORDER BY c.name DESC, c.age DESC |
Yes |
(name ASC, age ASC) |
SELECT * FROM c ORDER BY c.name ASC, c.age DESC |
No |
(name ASC, age ASC, timestamp ASC) |
SELECT * FROM c ORDER BY c.name ASC, c.age ASC, timestamp ASC |
Yes |
(name ASC, age ASC, timestamp ASC) |
SELECT * FROM c ORDER BY c.name ASC, c.age ASC |
No |
필요한 모든 ORDER BY
쿼리를 제공할 수 있도록 인덱싱 정책을 사용자 지정해야 합니다.
여러 속성에 대한 필터가 있는 쿼리
쿼리에 둘 이상의 속성에 대한 필터가 있는 경우 이러한 속성의 복합 인덱스를 만드는 것이 유용할 수 있습니다.
예를 들어 같음 필터와 범위 필터가 모두 있는 다음 쿼리를 고려해 보세요.
SELECT
*
FROM
container c
WHERE
c.name = "John" AND c.age > 18
복합 인덱스 (name ASC, age ASC)
를 적용할 수 있는 경우, 이 쿼리는 더 적은 시간과 요청 단위(RU)를 소비하면서 더 효율적으로 수행됩니다.
여러 범위 필터가 있는 쿼리는 복합 인덱스를 사용하여 최적화할 수도 있습니다. 그러나 개별 복합 인덱스는 단일 범위 필터만 최적화할 수 있습니다. 범위 필터에는 >
, <
, <=
, >=
및 !=
가 포함됩니다. 범위 필터는 복합 인덱스에서 마지막으로 정의되어야 합니다.
같음 필터 하나와 범위 필터 두 개가 있는 다음 쿼리를 생각해 보세요.
SELECT
*
FROM
container c
WHERE
c.name = "John" AND
c.age > 18 AND
c._ts > 1612212188
이 쿼리는 (name ASC, age ASC)
및 (name ASC, _ts ASC)
에 대한 복합 인덱스를 사용하여 더 효율적입니다. 하지만 같음 필터가 있는 속성이 복합 인덱스에서 먼저 정의되어야 하므로 이 쿼리는 (age ASC, name ASC)
에서 복합 인덱스를 활용하지 않습니다. 각 복합 인덱스는 단일 범위 필터만 최적화할 수 있으므로 (name ASC, age ASC, _ts ASC)
에서는 단일 복합 인덱스 대신 별도의 복합 인덱스 두 개가 필요합니다.
다음 고려 사항은 여러 속성에 대한 필터를 사용하여 쿼리에 대한 복합 인덱스를 만들 때 사용됩니다.
필터 식은 여러 복합 인덱스를 사용할 수 있습니다.
쿼리 필터의 속성은 복합 인덱스의 속성과 일치해야 합니다. 속성이 복합 인덱스이지만 쿼리에 필터로 포함되지 않은 경우 쿼리는 복합 인덱스 활용하지 않습니다.
복합 인덱스에 포함되지 않은 속성에 대한 쿼리 필터를 사용하면 복합 인덱스와 범위 인덱스의 조합이 쿼리를 평가하는 데 사용됩니다. 이 방법은 범위 인덱스에만 의존하는 것보다 RU를 적게 사용합니다.
속성에 범위 필터(
>
,<
,<=
,>=
또는!=
)가 있는 경우 이 속성은 복합 인덱스에서 마지막으로 정의되어야 합니다. 둘 이상의 범위 필터가 있는 쿼리는 여러 복합 인덱스를 활용할 수 있습니다.여러 필터를 사용하여 쿼리를 최적화하기 위해 복합 인덱스를 만들 때 복합 인덱스의
ORDER
결과는 영향을 주지 않습니다. 이 속성은 선택 사항입니다.
복합 인덱스가 속성 name, age, timestamp에서 정의되는 다음 예를 생각해 보세요.
복합 인덱스 | 샘플 쿼리 | 복합 인덱스가 지원합니까? |
---|---|---|
(name ASC, age ASC) |
SELECT * FROM c WHERE c.name = "John" AND c.age = 18 |
Yes |
(name ASC, age ASC) |
SELECT * FROM c WHERE c.name = "John" AND c.age > 18 |
Yes |
(name ASC, age ASC) |
SELECT COUNT(1) FROM c WHERE c.name = "John" AND c.age > 18 |
Yes |
(name DESC, age ASC) |
SELECT * FROM c WHERE c.name = "John" AND c.age > 18 |
Yes |
(name ASC, age ASC) |
SELECT * FROM c WHERE c.name != "John" AND c.age > 18 |
No |
(name ASC, age ASC, timestamp ASC) |
SELECT * FROM c WHERE c.name = "John" AND c.age = 18 AND c.timestamp > 123049923 |
Yes |
(name ASC, age ASC, timestamp ASC) |
SELECT * FROM c WHERE c.name = "John" AND c.age < 18 AND c.timestamp = 123049923 |
No |
(name ASC, age ASC) and (name ASC, timestamp ASC) |
SELECT * FROM c WHERE c.name = "John" AND c.age < 18 AND c.timestamp > 123049923 |
Yes |
필터 및 ORDER BY가 있는 쿼리
쿼리가 하나 이상의 속성에 대해 필터링하고 ORDER BY 절에서 다른 속성을 갖는 경우 필터의 속성을 ORDER BY
절에 추가하면 도움이 될 수 있습니다.
예를 들어 필터의 속성을 ORDER BY
절에 추가하면 다음 쿼리를 다시 작성하여 복합 인덱스를 적용할 수 있습니다.
범위 인덱스를 사용하여 쿼리:
SELECT
*
FROM
container c
WHERE
c.name = "John"
ORDER BY
c.timestamp
복합 인덱스를 사용하여 쿼리:
SELECT
*
FROM
container c
WHERE
c.name = "John"
ORDER BY
c.name,
c.timestamp
개별 복합 인덱스는 최대 하나의 범위 필터만 지원할 수 있다는 점을 명심하면 필터를 사용하는 어떤 ORDER BY
쿼리에도 동일한 쿼리 최적화를 일반화할 수 있습니다.
범위 인덱스를 사용하여 쿼리:
SELECT
*
FROM
container c
WHERE
c.name = "John" AND
c.age = 18 AND
c.timestamp > 1611947901
ORDER BY
c.timestamp
복합 인덱스를 사용하여 쿼리:
SELECT
*
FROM
container c
WHERE
c.name = "John" AND
c.age = 18 AND
c.timestamp > 1611947901
ORDER BY
c.name,
c.age,
c.timestamp
또한 복합 인덱스를 사용하여 시스템 함수와 함께 쿼리를 최적화할 수 있습니다 ORDER BY
.
범위 인덱스를 사용하여 쿼리:
SELECT
*
FROM
container c
WHERE
c.firstName = "John" AND
CONTAINS(c.lastName, "Smith", true)
ORDER BY
c.lastName
복합 인덱스를 사용하여 쿼리:
SELECT
*
FROM
container c
WHERE
c.firstName = "John" AND
CONTAINS(c.lastName, "Smith", true)
ORDER BY
c.firstName, c.lastName
필터 및 ORDER BY
절이 있는 쿼리를 최적화하기 위해 복합 인덱스를 만들 때는 다음 고려 사항이 적용됩니다.
하나의 속성에 대한 필터와 다른 속성을 사용하는 별도의
ORDER BY
절을 사용하여 쿼리에 복합 인덱스를 정의하지 않으면 쿼리는 여전히 성공합니다. 하지만 복합 인덱스를 사용하면, 특히ORDER BY
절의 속성에 높은 카디널리티가 있는 경우 쿼리의 RU 비용을 줄일 수 있습니다.쿼리가 속성을 필터링하는 경우 이러한 속성은
ORDER BY
절에 먼저 포함되어야 합니다.쿼리가 여러 속성을 필터링하는 경우 같음 필터가
ORDER BY
절의 첫 번째 속성이어야 합니다.쿼리가 여러 속성을 필터링하는 경우 복합 인덱스당 최대 하나의 범위 필터 또는 시스템 함수를 사용할 수 있습니다. 범위 필터 또는 시스템 함수에 사용되는 속성은 복합 인덱스에서 마지막으로 정의되어야 합니다.
여러 속성에 대한 필터가 있는 쿼리와 여러 속성이 있는
ORDER BY
쿼리를 위해 복합 인덱스를 만들 때의 모든 고려 사항이 계속 적용됩니다.
복합 인덱스 | 샘플 ORDER BY 쿼리 |
복합 인덱스가 지원합니까? |
---|---|---|
(name ASC, timestamp ASC) |
SELECT * FROM c WHERE c.name = "John" ORDER BY c.name ASC, c.timestamp ASC |
Yes |
(name ASC, timestamp ASC) |
SELECT * FROM c WHERE c.name = "John" AND c.timestamp > 1589840355 ORDER BY c.name ASC, c.timestamp ASC |
Yes |
(timestamp ASC, name ASC) |
SELECT * FROM c WHERE c.timestamp > 1589840355 AND c.name = "John" ORDER BY c.timestamp ASC, c.name ASC |
No |
(name ASC, timestamp ASC) |
SELECT * FROM c WHERE c.name = "John" ORDER BY c.timestamp ASC, c.name ASC |
No |
(name ASC, timestamp ASC) |
SELECT * FROM c WHERE c.name = "John" ORDER BY c.timestamp ASC |
No |
(age ASC, name ASC, timestamp ASC) |
SELECT * FROM c WHERE c.age = 18 and c.name = "John" ORDER BY c.age ASC, c.name ASC,c.timestamp ASC |
Yes |
(age ASC, name ASC, timestamp ASC) |
SELECT * FROM c WHERE c.age = 18 and c.name = "John" ORDER BY c.timestamp ASC |
No |
필터 하나와 집계 하나가 있는 쿼리
쿼리가 하나 이상의 속성을 필터링하고 집계 시스템 함수를 포함하는 경우 필터 및 집계 시스템 함수의 속성에 대한 복합 인덱스를 만드는 것이 유용할 수 있습니다. 이 최적화는 SUM
시스템 함수 및 AVG
시스템에 적용됩니다.
필터 및 집계 시스템 함수가 있는 쿼리를 최적화하기 위해 복합 인덱스를 만들 때는 다음 고려 사항이 적용됩니다.
복합 인덱스는 집계가 있는 쿼리를 실행할 때 선택 사항입니다. 하지만 복합 인덱스를 사용하면 쿼리의 RU 비용을 줄일 수 있는 경우가 많습니다.
쿼리가 여러 속성을 필터링하는 경우 같음 필터가 복합 인덱스의 첫 번째 속성이어야 합니다.
복합 인덱스당 최대 하나의 범위 필터를 사용할 수 있으며 범위 필터는 집계 시스템 함수의 속성에 있어야 합니다.
집계 시스템 함수의 속성은 복합 인덱스에서 마지막으로 정의되어야 합니다.
order
(ASC
또는DESC
)는 중요하지 않습니다.
복합 인덱스 | 샘플 쿼리 | 복합 인덱스가 지원합니까? |
---|---|---|
(name ASC, timestamp ASC) |
SELECT AVG(c.timestamp) FROM c WHERE c.name = "John" |
Yes |
(timestamp ASC, name ASC) |
SELECT AVG(c.timestamp) FROM c WHERE c.name = "John" |
No |
(name ASC, timestamp ASC) |
SELECT AVG(c.timestamp) FROM c WHERE c.name > "John" |
No |
(name ASC, age ASC, timestamp ASC) |
SELECT AVG(c.timestamp) FROM c WHERE c.name = "John" AND c.age = 25 |
Yes |
(age ASC, timestamp ASC) |
SELECT AVG(c.timestamp) FROM c WHERE c.name = "John" AND c.age > 25 |
No |
배열 와일드카드가 있는 복합 인덱스
다음은 배열 와일드카드를 포함하는 복합 인덱스의 예입니다.
{
"automatic": true,
"indexingMode": "Consistent",
"includedPaths": [
{
"path": "/*"
}
],
"excludedPaths": [],
"compositeIndexes": [
[
{
"path": "/familyname",
"order": "ascending"
},
{
"path": "/children/[]/age",
"order": "descending"
}
]
]
}
이 복합 인덱스에서 이점을 얻을 수 있는 예제 쿼리는 다음과 같습니다.
SELECT VALUE
p.id
FROM
products p
JOIN
t IN p.tags
WHERE
p.category = 'apparel' AND
p.order > 20
인덱싱 정책 수정
인덱싱 정책에 대한 업데이트는 이전 인덱스에서 새 인덱스로 변환을 트리거합니다. 이 변환은 현재 위치 및 온라인에서 수행됩니다. 작업 중에는 추가 스토리지 공간이 소비되지 않습니다. 이전 인덱싱 정책은 컨테이너의 쓰기 가용성, 읽기 가용성 또는 프로비전된 처리량에 영향을 주지 않고 새 인덱싱 정책으로 효율적으로 변환됩니다. 인덱스 변환은 비동기 작업이며, 완료하는 데 걸리는 시간은 프로비전된 처리량, 항목 수 및 크기에 따라 달라집니다. 여러 인덱싱 정책 업데이트를 수행해야 하는 경우 단일 작업에서 모든 변경 내용을 수행합니다. 이 방법을 사용하면 인덱스 변환을 더 빠르게 완료할 수 있습니다.
중요합니다
인덱스 변환은 요청 단위를 사용하는 작업입니다. SDK 중 하나를 사용하여 인덱스 변환 작업의 진행률 및 사용량을 추적할 수 있습니다.
인덱스 변환 중에는 쓰기 가용성에 영향을 주지 않습니다. 인덱스 변환은 프로비전된 RU를 사용하지만 CRUD 작업 또는 쿼리보다 낮은 우선 순위로 사용합니다.
새 인덱싱된 경로를 추가할 때 읽기 가용성에는 영향을 주지 않습니다. 쿼리는 인덱스 변환이 완료된 후에만 새 인덱싱된 경로를 사용합니다. 즉, 새 인덱싱된 경로를 추가할 때 해당 인덱싱된 경로를 활용하는 쿼리는 인덱스 변환 전과 도중에 동일한 성능을 갖습니다. 인덱스 변환이 완료된 후 쿼리 엔진은 새 인덱싱된 경로를 사용하기 시작합니다.
인덱싱된 경로를 제거할 때 모든 변경 사항을 하나의 인덱싱 정책 변환으로 그룹화해야 합니다. 여러 인덱스를 제거하고 하나의 단일 인덱싱 정책 변경에서 이를 수행하는 경우 쿼리 엔진은 인덱스 변환 전체에서 일관되고 완전한 결과를 제공합니다. 그러나 여러 인덱싱 정책 변경을 통해 인덱스를 제거하는 경우 쿼리 엔진은 모든 인덱스 변환이 완료될 때까지 일관되거나 완전한 결과를 제공하지 않습니다. 대부분의 개발자는 인덱스를 삭제하지 않고 즉시 이러한 인덱스를 활용하는 쿼리를 실행하려고 합니다. 실제로는 이 상황이 발생할 가능성이 낮습니다.
인덱싱된 경로를 삭제하면 쿼리 엔진이 즉시 사용을 중지하고 대신 전체 검사를 수행합니다. 가능한 경우 항상 여러 인덱스 제거를 단일 인덱싱 정책 수정으로 그룹화합니다.
인덱스를 제거하면 즉시 영향을 받는 반면 새 인덱스를 추가하려면 인덱싱 변환이 필요하므로 다소 시간이 걸립니다. 먼저 새 인덱을 추가한 다음 인덱스 변환 이 완료되기 를 기다린 후 인덱싱 정책에서 인덱스 하나를 다른 인덱스로 바꿀 때 이전 인덱스가 제거됩니다. 예를 들어 단일 속성 인덱스와 복합 인덱스로 바꿀 때 이 전략을 따릅니다. 그렇지 않으면 이 오류는 이전 인덱스를 쿼리하는 기능에 부정적인 영향을 미치며 이전 인덱스를 참조하는 활성 워크로드가 중단될 수 있습니다.
인덱싱 정책 및 TTL
TTL(Time to Live) 기능을 사용하려면 인덱싱이 필요합니다.
이는 다음을 요구한다는 것을 의미합니다.
인덱싱 모드가 로 설정된 컨테이너에서는 TTL을 활성화할 수
none
없습니다.TTL이 활성화된 컨테이너에서는 인덱싱 모드를 None으로 설정할 수 없습니다.
인덱싱해야 하는 속성 경로는 없지만 TTL이 필요한 시나리오의 경우 인덱싱 모드가 consistent
, 포함된 경로 없음, /*
로 설정된 인덱싱 정책을 유일한 제외된 경로로 사용할 수 있습니다.