쿼리 계획 검색

IBM Cloudant 쿼리가 쿼리를 실행할 때 사용하는 인덱스를 이해하는 것은 좋은 성능을 달성하는 데 필수적입니다. _explain 엔드포인트를 사용하여 쿼리 계획을 검색합니다.

인덱스 선택 방법

조회 시 인덱스를 지정하지 않는 한 IBM Cloudant 조회에서 조회에 응답하기 위해 사용할 인덱스를 선택합니다.

사용할 인덱스를 지정하지 않은 경우, IBM Cloudant Query는 다음의 논리를 사용합니다.

  • 조회 플래너에서 선택기 섹션을 확인한 후 조회에 사용되는 연산자 및 필드에 가장 근접한 일치 항목이 포함된 인덱스를 찾습니다. 둘 이상의 JSON 유형 인덱스가 일치하는 경우 인덱스의 필드 수가 가장 적은 인덱스가 선택됩니다. 여전히 둘 이상의 후보 인덱스가 존재하는 경우 알파벳순으로 첫 번째 이름의 인덱스가 선택됩니다.
  • json 유형 인덱스 text 유형 인덱스가 모두 선택기를 충족시킬 수 있는 경우 기본적으로 json 인덱스가 선택됩니다.
  • text 유형 인덱스는 다음 조건이 충족될 때 선택됩니다.
    • json 유형 인덱스 text 유형 인덱스가 동일한 필드에 존재합니다(예: fieldone).
    • 선택기는 text 유형 인덱스를 사용해야만 만족할 수 있습니다.

예를 들어 text 필드에 대한 json 유형 인덱스 및 foo 유형 인덱스가 존재하며 다음 샘플과 유사한 선택기를 사용하는 것으로 가정합니다.

{
	"foo": {
		"$in": ["red","blue","green"]
	}
}

text 유형 인덱스가 선택기를 충족시킬 수 없기 때문에 IBM Cloudant 조회에서 json 유형 인덱스를 사용합니다.

하지만 동일한 인덱스에 다른 선택기를 사용할 수 있습니다.

{
	"foo": {
		"$gt": 2
	}
}

이 예에서, IBM Cloudant Query는 두 유형의 인덱스 모두가 선택기를 충족할 수 있기 때문에 json 유형 인덱스를 사용합니다.

사용할 인덱스 지정

use_indexallow_fallback 쿼리 매개변수를 사용하여 쿼리에 대한 인덱스 사용을 제어합니다. 자세한 내용은 쿼리 매개변수를 참조하세요.

이러한 매개 변수를 사용할 때 _explain 은 쿼리가 지정된 인덱스를 사용할 수 있는지, 즉 쿼리가 의도한 대로 실행되는지 여부를 표시할 수 있습니다.

_explain 엔드포인트 사용

특정 조회에서 사용 중인 인덱스를 식별하려면 조회를 데이터로 사용하여 데이터베이스에 대한 POST 엔드포인트로 _explain를 전송하십시오. 사용 중인 인덱스에 대한 세부사항은 결과 내에 있는 index 오브젝트에 표시되어 있습니다.

다음과 같이 HTTP를 사용하여 조회에 응답하기 위해 사용된 인덱스를 식별하는 방법을 보여주는 예제를 참조하십시오.

POST /movies/_explain HTTP/1.1
Host: $SERVICE_URL
Content-Type: application/json
{
	"selector": {
		"$text": "Pacino",
		"year": 2010
	}
}

다음과 같이 명령행을 사용하여 조회에 응답하기 위해 사용된 인덱스를 식별하는 방법을 보여주는 예제를 참조하십시오.

curl "$SERVICE_URL/movies/_explain" \
	-X POST \
	-H "Content-Type: application/json" \
	-d '{
		"selector": {
			"$text": "Pacino",
			"year": 2010
		}
	}'
import com.ibm.cloud.cloudant.v1.Cloudant;
import com.ibm.cloud.cloudant.v1.model.ExplainResult;
import com.ibm.cloud.cloudant.v1.model.PostExplainOptions;

import java.util.HashMap;
import java.util.Map;

Cloudant service = Cloudant.newInstance();

Map<String, Object> selector = new HashMap<>();
selector.put("$text", "Pacino");
selector.put("year", 2010);

PostExplainOptions explainOptions =
    new PostExplainOptions.Builder()
        .db("movies")
        .selector(selector)
        .build();

ExplainResult response =
    service.postExplain(explainOptions).execute()
        .getResult();

System.out.println(response);
import { CloudantV1 } from '@ibm-cloud/cloudant';

const service = CloudantV1.newInstance({});

let selector: CloudantV1.Selector = {
    '$text': 'Pacino',
    'year': 2010
};

service.postExplain({
  db: 'movies',
  selector: selector
}).then(response => {
  console.log(response.result);
});
from ibmcloudant.cloudant_v1 import CloudantV1

service = CloudantV1.new_instance()

response = service.post_find(
  db='movies',
  selector={'$text': 'Pacino', 'year': 2010}
).get_result()

print(response)
postExplainOptions := service.NewPostExplainOptions(
    "movies",
    map[string]interface{}{
        "$text": "Pacino",
        "year":  2010,
    },
)

explainResult, _, err := service.PostExplain(postExplainOptions)
if err != nil {
  panic(err)
}

b, _ := json.MarshalIndent(explainResult, "", "  ")
fmt.Println(string(b))

이전 Go 예제에서는 다음 가져오기 블록이 필요합니다.

import (
   "encoding/json"
   "fmt"
   "github.com/IBM/cloudant-go-sdk/cloudantv1"
)

이 예제 _explain 응답은 쿼리에 응답하는 데 사용된 인덱스를 보여줍니다:

{
	"dbname": "$ACCOUNT/movies",
	"index": {
		"ddoc": "_design/32372935e14bed00cc6db4fc9efca0f1537d34a8",
		"name": "32372935e14bed00cc6db4fc9efca0f1537d34a8",
		"type": "text",
		"def": {
			"default_analyzer": "keyword",
			"default_field": {},
			"selector": {},
			"fields": []
		}
	},
	"selector": {
		"$and": [
			{
				"$default": {
					"$text": "Pacino"
				}
			},
			{
				"year": {
					"$eq": 2010
				}
			}
		]
	},
	"opts": {
		"use_index": [],
		"bookmark": [],
		"limit": 10000000000,
		"skip": 0,
		"sort": {},
		"fields": "all_fields",
		"r": [
			49
		],
		"conflicts": false
	},
	"limit": 200,
	"skip": 0,
	"fields": "all_fields",
	"query": "(($default:Pacino) AND (year_3anumber:2010))",
	"sort": "relevance"
}