Récupération des plans de requête

Pour obtenir de bonnes performances, il est essentiel de comprendre l'index utilisé par IBM Cloudant Query lors de l'exécution de vos requêtes. Utilisez le point d'accès _explain pour récupérer les plans de requête.

Comment les index sont-ils sélectionnés?

IBM Cloudant Query choisit l'index à utiliser pour répondre à une requête, sauf si vous spécifiez un index au moment de la requête.

Lorsque vous ne spécifiez pas d'index à utiliser, IBM Cloudant Query utilise la logique suivante :

  • Le planificateur de requête examine la section du sélecteur et recherche l'index correspondant le mieux aux opérateurs et aux zones utilisés dans la requête. Si deux index de type JSON ou plus correspondent, l'index dont le nombre de zones est le plus petit est préféré. Si deux index candidats ou plus existent encore, l'index qui apparaît en premier par ordre alphabétique est choisi.
  • Si un index de type json et un index de type text peuvent tous les deux satisfaire un sélecteur, l'index de type json est choisi par défaut.
  • L'index de type text est choisi lorsque les conditions suivantes sont remplies :
    • Un index de type json et un index de type text existent dans la même zone (par exemple, fieldone).
    • Le sélecteur ne peut être satisfait qu'à l'aide d'un index de type text.

Par exemple, vous disposez d'un index de type text et d'un index de type json pour la zone foo et voulez utiliser un sélecteur similaire à l'exemple suivant :

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

IBM Cloudant Query utilise l'index de type text car un index de type json ne peut pas satisfaire le sélecteur.

Toutefois, vous pouvez utiliser un autre sélecteur avec les mêmes index :

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

Dans cet exemple, IBM Cloudant Query utilise l'index de type json car les deux types d'index sont compatibles avec le sélecteur.

Spécification d'un index à utiliser

Utilisez les paramètres de requête use_index et allow_fallback pour contrôler l'utilisation de l'index pour les requêtes. Voir les paramètres de la requête pour plus de détails.

En utilisant ces paramètres, _explain peut montrer si les requêtes sont capables d'utiliser les index spécifiés, et donc si la requête s'exécutera comme prévu.

Utilisation du point de terminaison _explain

Pour identifier l'index qui est utilisé par une requête particulière, envoyez une demande POST au noeud final _explain pour la base de données, avec la requête comme données. Les détails de l'index utilisé sont affichés dans l'objet index dans le résultat.

Voici un exemple qui utilise HTTP pour identifier l'index qui a été utilisé pour répondre à une requête :

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

Voici un exemple qui utilise la ligne de commande pour identifier l'index qui a été utilisé pour répondre à une requête :

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

L'exemple précédent de Go requiert le bloc d'importation suivant :

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

Cet exemple de réponse _explain montre quel index a été utilisé pour répondre à une requête :

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