Recuperación de planes de consulta

Comprender el índice que utiliza IBM Cloudant Query al ejecutar sus consultas es esencial para lograr un buen rendimiento. Utilice el punto final _explain para recuperar planes de consulta.

Cómo se seleccionan los índices

IBM Cloudant Query elige el índice que se va a utilizar para responder a una consulta, a menos que especifique un índice en el momento de la consulta.

Cuando no se especifica un índice a utilizar, la Consulta de IBM Cloudant utiliza la lógica siguiente:

  • El planificador de consultas examina la sección del selector y encuentra el índice con la coincidencia más cercana a los operadores y los campos que se utilizan en la consulta. Si hay dos o más índices de tipo JSON que coinciden, se prefiere el índice con el número menor de campos de índice. Si siguen existiendo dos o más índices candidatos, se elige el índice con el primer nombre alfabético.
  • Si parece que un índice de tipo json y un índice de tipo text satisfacen un selector, el índice json se elige de forma predeterminada.
  • El índice de tipo text se elige cuando se cumplen las condiciones siguientes:
    • Un índice de tipo json y un índice de tipo text existe en el mismo campo (por ejemplo fieldone).
    • El selector solo se puede satisfacer mediante un índice de tipo text.

Por ejemplo, suponga que tiene un índice de tipo text y un índice de tipo json para el campo foo y desea utilizar un selector similar al siguiente:

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

IBM Cloudant Query utiliza el índice de tipo text porque un índice de tipo json no puede satisfacer el selector.

Sin embargo, puede utilizar un selector distinto con los mismos índices:

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

En este ejemplo, la Consulta de IBM Cloudant utiliza el índice de tipo json porque ambos tipos de índices pueden satisfacer el selector.

Especificación de un índice a utilizar

Utilice los parámetros de consulta use_index y allow_fallback para controlar el uso de índices en las consultas. Consulte Parámetros de consulta para obtener más información.

Al utilizar estos parámetros, _explain puede mostrar si las consultas son capaces de utilizar los índices especificados y, por tanto, si la consulta se ejecutará según lo previsto.

Utilización del punto final _explain

Para identificar el índice que está utilizando una consulta determinada, envíe un POST al punto final _explain para la base de datos, con la consulta como datos. Los detalles del índice que se está utilizando se muestran en el objeto index dentro del resultado.

Consulte el ejemplo siguiente que utiliza HTTP para mostrar cómo identificar el índice utilizado para responder a una consulta:

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

Consulte el ejemplo siguiente que utiliza la línea de mandatos para mostrar cómo identificar el índice utilizado para responder a una consulta:

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

El ejemplo Go anterior requiere el siguiente bloque de importación:

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

Este ejemplo de respuesta _explain muestra qué índice se ha utilizado para responder a una consulta:

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