Abfragepläne abrufen

Um eine gute Leistung zu erzielen, ist es wichtig, den Index zu verstehen, den IBM Cloudant Query bei der Ausführung Ihrer Abfragen verwendet. Verwenden Sie den Endpunkt _explain, um Abfragepläne abzurufen.

Wie Indizes ausgewählt werden

IBM Cloudant Query wählt den Index aus, der für die Beantwortung einer Abfrage zu verwenden ist, wenn Sie keinen Index in der Abfrage angeben.

Wenn Sie keinen zu verwendenden Index angeben, verwendet IBM Cloudant Query die folgende Logik:

  • Der Abfrageplaner untersucht den Selektorabschnitt und findet den Index mit der größten Übereinstimmung mit den Operatoren und Feldern, die in der Abfrage verwendet werden. Wenn zwei oder mehr Indizes vom Typ JSON übereinstimmen, wird der Index mit der kleinsten Anzahl von Feldern im Index bevorzugt. Wenn weiterhin zwei oder mehr Kandidatenindizes infrage kommen, wird der Index mit dem in alphabetischer Reihenfolge ersten Namen ausgewählt.
  • Wenn ein Index vom Typ json und ein Index vom Typ text einen Selektor erfüllen würden, wird standardmäßig der Index vom Typ json ausgewählt.
  • Der Index vom Typ text wird ausgewählt, wenn die folgenden Bedingungen erfüllt sind:
    • Ein Index vom Typ json und ein Index vom Typ text sind im selben Feld (z. B. fieldone) vorhanden.
    • Der Selektor kann nur mithilfe eines Index vom Typ text erfüllt werden.

Nehmen Sie zum Beispiel an, dass Sie einen Index vom Typ text und einen Index vom Typ json für das Feld foo haben und Sie einen Selektor ähnlich wie im folgenden Beispiel verwenden wollen:

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

IBM Cloudant Query verwendet den Index vom Typ text, weil ein Index vom Typ json den Selektor nicht erfüllen kann.

Sie könnten allerdings einen anderen Selektor mit denselben Indizes verwenden:

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

In diesem Beispiel verwendet IBM Cloudant Query den Index vom Typ json, weil die Indizes beider Typen den Selektor erfüllen können.

Angeben eines zu verwendenden Index

Verwenden Sie die Abfrageparameter use_index und allow_fallback, um die Verwendung von Indizes für Abfragen zu steuern. Siehe Abfrageparameter für weitere Einzelheiten.

Wenn diese Parameter verwendet werden, kann _explain zeigen, ob die Abfragen die angegebenen Indizes verwenden können und somit die Abfrage wie vorgesehen ausgeführt wird.

Verwendung des Endpunkts _explain

Zum Ermitteln, welcher Index für eine bestimmte Abfrage verwendet wird, senden Sie eine POST-Anforderung mit der Abfrage als Daten an den Endpunkt _explain für die Datenbank. Die Details des Index, der verwendet wird, werden im Objekt index im Ergebnis gezeigt.

Beispiel für eine HTTP-Anforderung, das zeigt, wie der Index ermittelt wird, der zur Beantwortung einer Abfrage verwendet wurde:

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

Beispiel für eine Anforderung über die Befehlszeile, das zeigt, wie der Index ermittelt wird, der zur Beantwortung einer Abfrage verwendet wurde:

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))

Das vorherige Go-Beispiel erfordert den folgenden Importblock:

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

Diese Beispielantwort _explain zeigt, welcher Index zur Beantwortung einer Abfrage verwendet wurde:

{
	"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"
}