{"id":4204,"date":"2017-11-12T14:08:59","date_gmt":"2017-11-12T22:08:59","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=4204"},"modified":"2025-06-13T20:20:14","modified_gmt":"2025-06-14T03:20:14","slug":"create-right-index-get-right-performance","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/es\/create-right-index-get-right-performance\/","title":{"rendered":"Crear el \u00edndice adecuado, obtener el rendimiento adecuado."},"content":{"rendered":"<h2><b>Introducci\u00f3n<\/b><\/h2>\n<p><span style=\"font-weight: 400\">Hay tres cosas importantes en los sistemas de bases de datos:<\/span><a href=\"https:\/\/sigmod.org\/publications\/interviews\/pdf\/p71-column-winslet.pdf\"> <span style=\"font-weight: 400\">rendimiento, rendimiento, rendimiento.<\/span><\/a><span style=\"font-weight: 400\"> Para los sistemas de bases de datos NoSQL, hay tres cosas importantes: <strong>rendimiento a escala, rendimiento a escala, rendimiento a escala<\/strong>.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Entender las opciones de \u00edndice, crear el \u00edndice correcto, con las claves correctas, el orden correcto y la expresi\u00f3n correcta es cr\u00edtico para el rendimiento de las consultas y el rendimiento a escala en Couchbase. <\/span><span style=\"font-weight: 400\">Hemos hablado de<\/span><a href=\"https:\/\/planetnosql.blogspot.com\/2016\/06\/keep-calm-and-json.html\"> <span style=\"font-weight: 400\">modelado de datos para JSON<\/span><\/a><span style=\"font-weight: 400\"> y<\/span><a href=\"https:\/\/planetnosql.blogspot.com\/2016\/07\/keep-calm-and-query-json.html\"> <span style=\"font-weight: 400\">consulta en JSON<\/span><\/a><span style=\"font-weight: 400\"> anterior. En este art\u00edculo, discutiremos las opciones de indexaci\u00f3n para JSON en Couchbase.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Couchbase 5.0 tiene tres tipos de categor\u00edas de \u00edndice. Cada cl\u00faster de Couchbase solo puede tener una categor\u00eda de \u00edndice, ya sea \u00edndice secundario global est\u00e1ndar o \u00edndice secundario global optimizado para memoria.<\/span><\/p>\n<table>\n<tbody>\n<tr>\n<td><span style=\"font-weight: 400\">Secundaria est\u00e1ndar: versi\u00f3n 4.0 y superior<\/span><\/td>\n<td>\n<ul>\n<li><span style=\"font-weight: 400\">Basado en ForestDB<\/span><\/li>\n<li>Lanzado con Couchbase 4.0<\/li>\n<\/ul>\n<\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\">\u00cdndice de memoria optimizada: 4,5 y superior<\/span><\/td>\n<td>\n<ul>\n<li><span style=\"font-weight: 400\">100% del \u00edndice est\u00e1 en la memoria<\/span><\/li>\n<li>El \u00edndice se escribe en el disco s\u00f3lo para recuperaci\u00f3n<\/li>\n<li><span style=\"font-weight: 400\">Rendimiento previsible<\/span><\/li>\n<li><span style=\"font-weight: 400\">Mejor tasa de mutaci\u00f3n<\/span><\/li>\n<\/ul>\n<\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\">Secundaria est\u00e1ndar: versi\u00f3n 5.0<\/span><\/td>\n<td>\n<ul>\n<li><span style=\"font-weight: 400\">Utiliza el motor de almacenamiento Plasma basado en listas de esqu\u00ed sin bloqueo para nuestra edici\u00f3n empresarial.<\/span><\/li>\n<li>Utiliza el motor de almacenamiento ForestDB para la edici\u00f3n comunitaria<\/li>\n<li><span style=\"font-weight: 400\">Lanzado con Couchbase 5.0.<\/span><\/li>\n<li><span style=\"font-weight: 400\">Dise\u00f1ado para manejar conjuntos de datos muy grandes<\/span><\/li>\n<\/ul>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><span style=\"font-weight: 400\">El \u00edndice secundario est\u00e1ndar (de 4.0 a 4.6.x) almacena utiliza el motor de almacenamiento ForestDB para almacenar el \u00edndice B-Tree y mantiene el conjunto \u00f3ptimo de trabajo de los datos en el buffer. Esto significa que el tama\u00f1o total del \u00edndice puede ser mucho mayor que la cantidad de memoria disponible en cada nodo de \u00edndice.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Un \u00edndice optimizado para memoria utiliza una novedosa lista de esqu\u00ed sin bloqueos para mantener el \u00edndice y conserva 100% de los datos del \u00edndice en memoria. Un \u00edndice optimizado para memoria (MOI) tiene mejor latencia para las exploraciones del \u00edndice y tambi\u00e9n puede procesar las mutaciones de los datos mucho m\u00e1s r\u00e1pido. <\/span><\/p>\n<p><span style=\"font-weight: 400\">El \u00edndice secundario est\u00e1ndar de la versi\u00f3n 5.0 utiliza el motor de almacenamiento plasma de nuestra edici\u00f3n empresarial, que utiliza la lista de exclusi\u00f3n sin bloqueo como MOI, pero admite \u00edndices de gran tama\u00f1o que no caben en la memoria.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Los tres tipos de \u00edndices implementan el control de concurrencia multiversi\u00f3n (MVCC) para proporcionar resultados de escaneo de \u00edndices consistentes y un alto rendimiento. Durante la instalaci\u00f3n del cl\u00faster, elija el tipo de \u00edndice.<\/span><\/p>\n<p><span style=\"font-weight: 400\">El objetivo es ofrecerle una visi\u00f3n general de los distintos \u00edndices que se crean en cada uno de estos servicios para que sus consultas puedan ejecutarse de forma eficiente. El objetivo de este art\u00edculo no es describir o comparar y contrastar estos dos tipos de servicios de \u00edndice. No cubre el \u00cdndice de B\u00fasqueda de Texto Completo (FTS), lanzado en Couchbase 5.0. <\/span><\/p>\n<p><span style=\"font-weight: 400\">Tomemos el <strong>viaje-muestra<\/strong> y probar estos \u00edndices. <\/span><\/p>\n<p><span style=\"font-weight: 400\">En la consola web, vaya a <strong>Configuraci\u00f3n-&gt;Cubos de muestra<\/strong> para instalar la muestra de viaje.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Aqu\u00ed tienes los distintos \u00edndices que puedes crear.<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400\"><a href=\"https:\/\/www.couchbase.com\/blog\/es\/primary-uses-for-couchbase-primary-index\/\"><strong>\u00cdndice primario<\/strong><\/a><\/li>\n<li style=\"font-weight: 400\"><strong>\u00cdndice primario con nombre<\/strong><\/li>\n<li style=\"font-weight: 400\"><strong>\u00cdndice secundario<\/strong><\/li>\n<li style=\"font-weight: 400\"><strong>\u00cdndice compuesto secundario<\/strong><\/li>\n<li style=\"font-weight: 400\"><strong>\u00cdndice funcional<\/strong><\/li>\n<li style=\"font-weight: 400\"><strong>\u00cdndice de matrices<\/strong><\/li>\n<li style=\"font-weight: 400\"><strong>matriz ALL<\/strong><\/li>\n<li style=\"font-weight: 400\"><strong>matriz ALL DISTINCT<\/strong><\/li>\n<li style=\"font-weight: 400\"><strong>\u00cdndice parcial<\/strong><\/li>\n<li style=\"font-weight: 400\"><strong>\u00cdndice adaptativo<\/strong><\/li>\n<li style=\"font-weight: 400\"><strong>\u00cdndices duplicados<\/strong><\/li>\n<li style=\"font-weight: 400\"><strong>\u00cdndice de cobertura<\/strong><\/li>\n<\/ul>\n<h2><b>Fondo<\/b><\/h2>\n<p><span style=\"font-weight: 400\">Couchbase es una base de datos distribuida. Soporta un modelo de datos flexible usando JSON. Cada documento en un bucket tendr\u00e1 una clave de documento \u00fanica generada por el usuario. Esta unicidad se aplica durante la inserci\u00f3n de los datos.<\/span><\/p>\n<p><span style=\"font-weight: 400\">He aqu\u00ed un documento de ejemplo.<\/span><\/p>\n<pre class=\"font-size:17 line-height:20 lang:mysql decode:true\">SELECT meta().id, travel\r\n  FROM `travel-sample` travel\r\n  WHERE type = 'airline' limit 1;\r\n\r\n[\r\n  {\r\n    \"id\": \"airline_10\",\r\n      \"travel\": {\r\n        \"callsign\": \"MILE-AIR\",\r\n        \"country\": \"United States\",\r\n        \"iata\": \"Q5\",\r\n        \"icao\": \"MLA\",\r\n        \"id\": 10,\r\n        \"name\": \"40-Mile Air\",\r\n        \"type\": \"airline\"\r\n      }\r\n   }\r\n]\r\n<\/pre>\n<h2><b>Tipo de \u00edndices<\/b><\/h2>\n<h3><b>1. \u00cdndice primario<\/b><\/h3>\n<p><span style=\"font-weight: 400\">crea el \u00edndice primario en <strong>\"viaje-muestra\":<\/strong><\/span><\/p>\n<p><span style=\"font-weight: 400\">El \u00edndice primario es simplemente el \u00edndice de la clave de documento de todo el bucket. La capa de datos de Couchbase impone la restricci\u00f3n de unicidad en la clave del documento. El \u00edndice primario, como cualquier otro \u00edndice en Couchbase, se mantiene de forma as\u00edncrona. Se puede establecer la recencia de los datos estableciendo el par\u00e1metro <\/span><a href=\"https:\/\/developer.couchbase.com\/documentation\/server\/current\/architecture\/querying-data-with-n1ql.html\"><span style=\"font-weight: 400\">nivel de coherencia<\/span><\/a><span style=\"font-weight: 400\"> para su consulta.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Estos son los metadatos de este \u00edndice:<\/span><\/p>\n<pre class=\"font-size:17 line-height:20 lang:default decode:true\">SELECT * \r\n  FROM system:indexes \r\n  WHERE name = \u2018#primary\u2019;\r\n\r\n\"indexes\": {\r\n  \"datastore_id\": \"https:\/\/127.0.0.1:8091\",\r\n  \"id\": \"f6e3c75d6f396e7d\",\r\n  \"index_key\": [],\r\n  \"is_primary\": true,\r\n  \"keyspace_id\": \"travel-sample\",\r\n  \"name\": \"#primary\",\r\n  \"namespace_id\": \"default\",\r\n  \"state\": \"online\",\r\n  \"using\": \"gsi\"\r\n}\r\n<\/pre>\n<p><span style=\"font-weight: 400\">Los metadatos proporcionan informaci\u00f3n adicional sobre el \u00edndice: D\u00f3nde reside el \u00edndice (datastore_id), su estado (state) y el m\u00e9todo de indexaci\u00f3n (using).<\/span><\/p>\n<p><span style=\"font-weight: 400\">El \u00edndice primario se utiliza para escaneos de bucket completos (escaneos primarios) cuando la consulta no tiene ning\u00fan filtro (predicados) o se puede utilizar otro \u00edndice o ruta de acceso.  En Couchbase, almacenas m\u00faltiples keyspaces (documentos de diferente tipo, clientes, pedidos, inventario, etc) en un \u00fanico bucket. Entonces, cuando haces el escaneo primario, la consulta usar\u00e1 el \u00edndice para obtener las claves de los documentos y buscar\u00e1 todos los documentos en el bucket y luego aplicar\u00e1 el filtro. Esto es MUY CARO.<\/span><\/p>\n<p><span style=\"font-weight: 400\">El dise\u00f1o de la clave de documento es algo as\u00ed como un dise\u00f1o de clave primaria con m\u00faltiples partes.<\/span><\/p>\n<p><span class=\"font-size:17 line-height:20 lang:mysql decode:true crayon-inline\">Apellido:nombre:ID cliente <\/span><\/p>\n<p><span class=\"font-size:17 line-height:20 lang:mysql decode:true crayon-inline\">Example: smith:john:X1A1849 <\/span><\/p>\n<p><span style=\"font-weight: 400\">En Couchbase, es una buena pr\u00e1ctica prefijar la clave con el tipo de documento. Dado que se trata de un documento de cliente, pongamos el prefijo CX. Ahora, la clave se convierte en:<\/span><\/p>\n<pre class=\"font-size:17 line-height:20 lang:mysql decode:true\">Ejemplo: CX:smith:juan:X1A1849\r\n<\/pre>\n<p><span style=\"font-weight: 400\">As\u00ed que, en el mismo cubo, habr\u00e1 otros tipos de documentos.<\/span><\/p>\n<pre class=\"font-size:17 line-height:20 lang:mysql decode:true\">Tipo de ORDEN:  OD:US:CA:294829\r\n<\/pre>\n<pre class=\"font-size:17 line-height:20 lang:mysql decode:true\">ITEMS  type: IT:KD93823\r\n<\/pre>\n<p><span style=\"font-weight: 400\">Estas son simplemente las mejores pr\u00e1cticas. No hay restricciones sobre el formato o la estructura de la clave del documento en Couchbase, excepto que tienen que ser \u00fanicas dentro de un bucket.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Ahora, si tienes documentos con varias claves y tienes un \u00edndice primario, puedes utilizar las siguientes consultas de forma eficiente.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Ejemplo 1: B\u00fasqueda de una clave de documento espec\u00edfica.<\/span><\/p>\n<pre class=\"font-size:17 line-height:20 lang:mysql decode:true\">SELECT * \r\n  FROM sales \r\n  WHERE META().id = \u201cCX:smith:john:X1A1849\u201d;\r\n\r\n{\r\n  \"#operator\": \"IndexScan2\",\r\n  \"index\": \"#primary\",\r\n  \"index_id\": \"4c92ab0bcca9690a\",\r\n  \"keyspace\": \"sales\",\r\n  \"namespace\": \"default\",\r\n  \"spans\": [\r\n    {\r\n      \"exact\": true,\r\n      \"range\": [\r\n        {\r\n          \"high\": \"\\\"CX:smith:john:X1A1849\\\"\",\r\n          \"inclusion\": 3,\r\n          \"low\": \"\\\"CX:smith:john:X1A1849\\\"\"\r\n        }\r\n      ]\r\n    }\r\n  ],\r\n}<\/pre>\n<p><span style=\"font-weight: 400\">Si conoce la clave completa del documento, puede utilizar la siguiente sentencia y evitar por completo el acceso al \u00edndice.<\/span><\/p>\n<p><span class=\"theme:dark-terminal lang:default decode:true crayon-inline\">SELECT * FROM sales USE KEYS [\u201cCX:smith:john:X1A1849\u201d] <\/span><\/p>\n<p><span style=\"font-weight: 400\">Puede obtener m\u00e1s de un documento en una declaraci\u00f3n.<\/span><\/p>\n<pre class=\"font-size:17 line-height:20 lang:mysql decode:true\">SELECT * FROM ventas USE KEYS [\"CX:smith:john:X1A1849\", \"CX:smithjr:john:X2A1492\"].\r\n<\/pre>\n<p><b>Ejemplo 2:<\/b><span style=\"font-weight: 400\"> Busque un patr\u00f3n. Consigue TODOS los documentos del cliente.<\/span><\/p>\n<pre class=\"font-size:17 line-height:20 lang:mysql decode:true\">SELECT * \r\n  FROM sales \r\n  WHERE META().id \r\n  LIKE \u201cCX:%\u201d;\r\n\r\n{\r\n  \"#operator\": \"IndexScan2\",\r\n  \"index\": \"#primary\",\r\n  \"index_id\": \"4c92ab0bcca9690a\",\r\n  \"keyspace\": \"sales\",\r\n  \"namespace\": \"default\",\r\n  \"spans\": [\r\n    {\r\n      \"exact\": true,\r\n      \"range\": [\r\n        {\r\n          \"high\": \"\\\"CX;\\\"\",\r\n           \"inclusion\": 1,\r\n           \"low\": \"\\\"CX:\\\"\"\r\n        }\"\r\n      ]\r\n    }\r\n  ],\r\n}<\/pre>\n<p><b>Ejemplo 3:<\/b><span style=\"font-weight: 400\"> Consiga todos los clientes con <strong>\"herrero\"<\/strong> como apellido.<\/span><\/p>\n<p><span style=\"font-weight: 400\">La siguiente consulta utiliza el \u00edndice primario de forma eficiente, obteniendo \u00fanicamente los clientes con un rango determinado.<\/span> <b>Nota:<\/b><span style=\"font-weight: 400\"> Este escaneo distingue entre may\u00fasculas y min\u00fasculas. Para realizar una exploraci\u00f3n sin distinguir may\u00fasculas de min\u00fasculas, puede crear un \u00edndice secundario con UPPER() o LOWER() de la clave del documento.<\/span><\/p>\n<pre class=\"font-size:17 line-height:20 lang:mysql decode:true\">SELECT * \r\n  FROM sales \r\n  WHERE META().id \r\n  LIKE \"CX:smith%\";\r\n\r\n{\r\n  \"#operator\": \"IndexScan2\",\r\n  \"index\": \"#primary\",\r\n  \"index_id\": \"4c92ab0bcca9690a\",\r\n  \"keyspace\": \"sales\",\r\n  \"namespace\": \"default\",\r\n  \"spans\": [\r\n    {\r\n      \"exact\": true,\r\n      \"range\": [\r\n        {\r\n          \"high\": \"\\\"CX:smiti\\\"\",\r\n          \"inclusion\": 1,\r\n          \"low\": \"\\\"CX:smith\\\"\"\r\n        }\r\n      ]\r\n    }\r\n  ],\r\n}<\/pre>\n<p><b>Ejemplo 4:<\/b><span style=\"font-weight: 400\"> Es habitual que algunas aplicaciones utilicen una direcci\u00f3n de correo electr\u00f3nico como parte del documento, ya que son valores \u00fanicos. En ese caso, necesita averiguar todos los clientes con \"@gmail.com\". Si este es un requerimiento t\u00edpico, entonces, almacene el REVERSO de la direcci\u00f3n de correo electr\u00f3nico como la clave y simplemente haga el escaneo del patr\u00f3n de cadena l\u00edder.<\/span><\/p>\n<p><span class=\"font-size:17 line-height:20 lang:default decode:true crayon-inline\">Email:johnsmith@gmail.com; &amp;nbsp;&amp;nbsp;key: reverse(&#8220;johnsmith@gmail.com&#8221;) =&gt; moc.liamg@htimsnhoj\u00a0<\/span><\/p>\n<p><span class=\"font-size:17 line-height:20 lang:default decode:true crayon-inline\">Email: janesnow@yahoo.com &amp;nbsp;key: reverse(&#8220;janesnow@yahoo.com&#8221;) =&gt; moc.oohay@wonsenaj<\/span><\/p>\n<pre class=\"font-size:17 line-height:20 lang:mysql decode:true\">SELECT *\r\n  FROM sales\r\n  WHERE meta().id \r\n  LIKE (reverse(\"@yahoo.com\") || \"%\");\r\n\r\n{\r\n  \"#operator\": \"IndexScan2\",\r\n  \"index\": \"#primary\",\r\n  \"index_id\": \"4c92ab0bcca9690a\",\r\n  \"keyspace\": \"sales\",\r\n  \"namespace\": \"default\",\r\n  \"spans\": [\r\n    {\r\n      \"range\": [\r\n        {\r\n          \"high\": \"\\\"moc.oohayA\\\"\",\r\n          \"inclusion\": 1,\r\n          \"low\": \"\\\"moc.oohay@\\\"\"\r\n        }\r\n      ]\r\n    }\r\n  ],\r\n}<\/pre>\n<h3><b>2. \u00cdndice primario con nombre<\/b><\/h3>\n<p><span style=\"font-weight: 400\">En Couchbase 5.0, puedes crear m\u00faltiples r\u00e9plicas de cualquier \u00edndice con un simple par\u00e1metro a CREATE INDEX. Lo siguiente crear\u00e1 3 copias del \u00edndice y tiene que haber un m\u00ednimo de 3 nodos de \u00edndice en el cl\u00faster.<\/span><\/p>\n<pre class=\"font-size:17 line-height:20 lang:mysql decode:true\">CREAR \u00cdNDICE PRIMARIO EN `viaje-muestra` CON {\"num_replica\":2};\r\nCREATE PRIMARY INDEX `def_primary` ON `viaje-muestra` ;<\/pre>\n<p><span style=\"font-weight: 400\">Tambi\u00e9n puede asignar un nombre al \u00edndice primario. El resto de las caracter\u00edsticas del \u00edndice primario son las mismas, excepto el nombre del \u00edndice. Un buen efecto secundario de esto es que puedes tener m\u00faltiples \u00edndices primarios en versiones de Couchbase anteriores a la 5.0 usando diferentes nombres. Los \u00edndices duplicados ayudan a la alta disponibilidad as\u00ed como a la distribuci\u00f3n de la carga de consultas a trav\u00e9s de ellos. Esto es cierto tanto para los \u00edndices primarios como para los secundarios.<\/span><\/p>\n<pre class=\"font-size:17 line-height:20 whitespace-before:1 whitespace-after:01 lang:mysql decode:true\">SELECT meta().id as documentkey, `travel-sample` airline\r\n  FROM `travel-sample`\r\n  WHERE type = 'airline' limit 1;\r\n\r\n{\r\n  \"airline\": {\r\n    \"callsign\": \"MILE-AIR\",\r\n    \"country\": \"United States\",\r\n    \"iata\": \"Q5\",\r\n    \"icao\": \"MLA\",\r\n    \"id\": 10,\r\n    \"name\": \"40-Mile Air\",\r\n    \"type\": \"airline\"\r\n  },\r\n  \"documentkey\": \"airline_10\"\r\n}\r\n<\/pre>\n<h3><b>3. \u00cdndice secundario<\/b><\/h3>\n<p><span style=\"font-weight: 400\">El \u00edndice secundario es un \u00edndice sobre cualquier clave-valor o clave-documento. Este \u00edndice puede ser cualquier clave dentro del documento. La clave puede ser de cualquier tipo: escalar, objeto o matriz. La consulta tiene que utilizar el mismo tipo de objeto para que el motor de consulta pueda explotar el \u00edndice.<\/span><\/p>\n<pre class=\"font-size:17 line-height:20 lang:mysql decode:true\">CREATE INDEX travel_name ON `travel-sample`(name);\r\n\r\nname is a simple scalar value.\r\n{\r\n  \"name\": \"Air France\"\r\n}\r\n\r\nCREATE INDEX travel_geo on `travel-sample`(geo);\r\n\r\ngeo is an object embedded within the document. Example:\r\n\r\n\"geo\": {\r\n  \"alt\": 12,\r\n  \"lat\": 50.962097,\r\n  \"lon\": 1.954764\r\n}\r\n\r\nCreating indexes on keys from nested objects is straightforward.\r\nCREATE INDEX travel_geo on `travel-sample`(geo.alt);\r\nCREATE INDEX travel_geo on `travel-sample`(geo.lat);<\/pre>\n<p><span style=\"font-weight: 400\">El campo horario es una matriz de objetos con los detalles del vuelo. Esto indexa el array completo. No es exactamente \u00fatil a menos que est\u00e9s buscando el array completo.<\/span><\/p>\n<pre class=\"font-size:17 line-height:20 lang:mysql decode:true\">CREATE INDEX travel_schedule ON `travel-sample`(schedule);\r\n\r\nExample:\r\n\r\n\"schedule\": [\r\n  {\r\n     \"day\": 0,\r\n     \"flight\": \"AF198\",\r\n     \"utc\": \"10:13:00\"\r\n  },\r\n  {\r\n     \"day\": 0,\r\n     \"flight\": \"AF547\",\r\n     \"utc\": \"19:14:00\"\r\n  },\r\n  {\r\n     \"day\": 0,\r\n     \"flight\": \"AF943\",\r\n     \"utc\": \"01:31:00\"\r\n  },\r\n  {\r\n    \"day\": 1,\r\n    \"flight\": \"AF356\",\r\n    \"utc\": \"12:40:00\"\r\n  },\r\n  {\r\n    \"day\": 1,\r\n    \"flight\": \"AF480\",\r\n    \"utc\": \"08:58:00\"\r\n  },\r\n  {\r\n     \"day\": 1,\r\n     \"flight\": \"AF250\",\r\n     \"utc\": \"12:59:00\"\r\n  }\r\n]\r\n<\/pre>\n<h3><b>4. \u00cdndice secundario compuesto<\/b><\/h3>\n<p><span style=\"font-weight: 400\">Es com\u00fan tener consultas con m\u00faltiples filtros (predicados). Por lo tanto, se desean \u00edndices con m\u00faltiples claves para que los \u00edndices puedan devolver s\u00f3lo las claves cualificadas de los documentos. Adem\u00e1s, si una consulta s\u00f3lo hace referencia a las claves del \u00edndice, el motor de consulta simplemente responder\u00e1 a la consulta a partir del resultado de la exploraci\u00f3n del \u00edndice sin ir a los nodos de datos. Se trata de una optimizaci\u00f3n de rendimiento muy utilizada.<\/span><\/p>\n<pre class=\"font-size:17 line-height:20 lang:default decode:true\">CREATE INDEX idx_stctln ON&amp;nbsp; `travel-sample` (state, city, name.lastname)<\/pre>\n<p><span style=\"font-weight: 400\">Cada una de las claves puede ser un campo escalar simple, un objeto o una matriz. Para que se pueda aprovechar el filtrado de \u00edndices, los filtros tienen que utilizar el tipo de objeto correspondiente en el filtro de consulta. Las claves de los \u00edndices secundarios pueden incluir claves de documento (meta().id) expl\u00edcitamente si es necesario filtrar sobre ellas en el \u00edndice.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Veamos las consultas que aprovechan y las que no aprovechan el \u00edndice.<\/span><\/p>\n<pre class=\"font-size:17 line-height:20 wrap:true scroll:true whitespace-before:2 lang:mysql decode:true\">1.SELECT * FROM `travel-sample` WHERE state = 'CA';\r\nThe predicate matches the leading key of the index. So, this query uses the index to fully evaluate the predicate (state = \u2018CA\u2019). \r\n\r\n2.SELECT * FROM `travel-sample` WHERE state = 'CA' AND city = 'Windsor';\r\nThe predicates match the leading two keys. So this is good fit as well.\r\n\r\n3.SELECT * FROM `travel-sample` WHERE state = 'CA' AND city = 'Windsor' AND name.lastname = 'smith';\r\n\r\nThe three predicates in this query matches the three index keys perfectly. So, this is a good match.\r\n\r\n4.SELECT * FROM `travel-sample` WHERE city = 'Windsor' AND name.lastname = 'smith';\r\n\r\nIn this query, although predicates match two of the index keys, the leading key isn\u2019t matched. So, the index cannot and is not used for this query plans.\r\n\r\n5.SELECT * FROM `travel-sample` WHERE name.lastname = 'smith';\r\nSimilar to previous query, this query has the predicate on the third key of the index. So, this index cannot be used.\r\n\r\n6.SELECT * FROM `travel-sample` WHERE state = 'CA' AND name.lastname = 'smith';\r\n\r\nThis query has predicate on first and the third key. While this index is and can be chosen, we cannot push down the predicate after skipping an index key (second key in this case). So, only the first predicate (state = \"CA\") will be pushed down to index scan.\r\n\r\n\"#operator\": \"IndexScan2\",\r\n\"index\": \"idx_stctln\",\r\n\"index_id\": \"dadbb12da565ed28\",\r\n\"index_projection\": {\r\n  \"primary_key\": true\r\n},\r\n\"keyspace\": \"travel-sample\",\r\n\"namespace\": \"default\",\r\n\"spans\": [\r\n  {\r\n    \"exact\": true,\r\n    \"range\": [\r\n      {\r\n        \"high\": \"\\\"CA\\\"\",\r\n        \"inclusion\": 3,\r\n        \"low\": \"\\\"CA\\\"\"\r\n      }\r\n   ]\r\n}\r\n\r\n7.SELECT * FROM `travel-sample` WHERE state IS NOT MISSING AND city = 'Windsor' AND name.lastname = 'smith';\r\n \r\nThis is a modified version of query 4 above. To use this index, the query needs to have an additional predicate (state IS NOT MISSING) assuming that represents your application requirement.\r\n<\/pre>\n<h3><b>5. \u00cdndice funcional (expresi\u00f3n)<\/b><\/h3>\n<p><span style=\"font-weight: 400\">Es habitual tener nombres en la base de datos con una mezcla de may\u00fasculas y min\u00fasculas. Cuando necesites buscar \"Juan\", quieres que busque cualquier combinaci\u00f3n de \"Juan\", \"juan\", etc. As\u00ed es como se hace.<\/span><\/p>\n<p><span class=\"font-size:17 line-height:20 lang:mysql decode:true crayon-inline\">CREATE INDEX travel_cxname ON `travel-sample`(LOWER(name)); <\/span><\/p>\n<p><span style=\"font-weight: 400\">Proporcione la cadena de b\u00fasqueda en min\u00fasculas y el \u00edndice buscar\u00e1 eficazmente los valores ya escritos en min\u00fasculas en el \u00edndice.<\/span><\/p>\n<pre class=\"font-size:17 line-height:20 lang:mysql decode:true\">EXPLAIN SELECT * FROM `travel-sample` WHERE LOWER(name) = \"john\";\r\n\r\n{\r\n  \"#operator\": \"IndexScan\",\r\n  \"index\": \"travel_cxname\",\r\n  \"index_id\": \"2f39d3b7aac6bbfe\",\r\n  \"keyspace\": \"travel-sample\",\r\n  \"namespace\": \"default\",\r\n  \"spans\": [\r\n    {\r\n      \"Range\": {\r\n        \"High\": [\r\n          \"\\\"john\\\"\"\r\n        ],\r\n        \"Inclusion\": 3,\r\n        \"Low\": [\r\n          \"\\\"john\\\"\"\r\n        ]\r\n      }\r\n    }\r\n  ]\r\n}<\/pre>\n<p><span style=\"font-weight: 400\">Puede utilizar expresiones complejas en este \u00edndice funcional.<\/span><\/p>\n<p><span class=\"font-size:17 line-height:20 whitespace-before:1 lang:mysql decode:true crayon-inline\">CREATE INDEX travel_cx1 ON `travel-sample`(LOWER(name),\u00a0length*width, round(salary)); <\/span><\/p>\n<p><span style=\"font-weight: 400\">Tambi\u00e9n ver\u00e1s que se pueden crear \u00edndices de array en una expresi\u00f3n que devuelva un array en la siguiente secci\u00f3n.<\/span><\/p>\n<h3><b>6. \u00cdndice de matrices<\/b><\/h3>\n<p><span style=\"font-weight: 400\">JSON es jer\u00e1rquico. En el nivel superior, puede tener campos escalares, objetos o matrices. Cada objeto puede anidar otros objetos y matrices. Cada array puede tener otros objetos y arrays. Y as\u00ed sucesivamente. El anidamiento contin\u00faa.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Cuando tienes esta rica estructura, as\u00ed es como indexas un array particular o un campo dentro del sub-objeto.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Considera la matriz, programa:<\/span><\/p>\n<pre class=\"font-size:17 line-height:20 lang:mysql decode:true\">schedule: [\r\n  {\r\n    \"day\" : 0,\r\n    \"special_flights\" :\r\n      [\r\n        {\r\n          \"flight\" : \"AI111\", \"utc\" : \u201d1:11:11\"\r\n        },\r\n        {\r\n          \"flight\" : \"AI222\", \"utc\" : \u201d2:22:22\"\r\n        }  \r\n      ]\r\n    },\r\n  {\r\n    \"day\": 1,\r\n    \"flight\": \"AF552\",\r\n    \"utc\": \"14:41:00\u201d\r\n  }\r\n]\r\n\r\nCREATE INDEX travel_sched ON `travel-sample`\r\n(ALL DISTINCT ARRAY v.day FOR v IN schedule END)\r\n<\/pre>\n<p><span style=\"font-weight: 400\">v es la variable que hemos declarado impl\u00edcitamente para hacer referencia a cada elemento\/objeto dentro de la matriz: schedule v.day hace referencia al elemento dentro de cada objeto de la matriz schedule.<\/span><\/p>\n<p><span style=\"font-weight: 400\">La siguiente consulta explotar\u00e1 el \u00edndice del array.<\/span><\/p>\n<pre class=\"font-size:17 line-height:20 lang:mysql decode:true\">EXPLAIN SELECT * FROM `travel-sample` WHERE ANY v IN SCHEDULE SATISFIES v.day = 2 END;\r\n\r\n{\r\n  \"#operator\": \"DistinctScan\",\r\n  \"scan\": {\r\n    \"#operator\": \"IndexScan\",\r\n    \"index\": \"travel_sched\",\r\n    \"index_id\": \"db7018bff5f10f17\",\r\n    \"keyspace\": \"travel-sample\",\r\n    \"namespace\": \"default\",\r\n    \"spans\": [\r\n      {\r\n        \"Range\": {\r\n           \"High\": [\r\n             \"2\"\r\n           ],\r\n           \"Inclusion\": 3,\r\n           \"Low\": [\r\n             \"2\"\r\n           ]\r\n         }\r\n       }\r\n    ],\r\n  \"using\": \"gsi\"\r\n}\r\n<\/pre>\n<p><span style=\"font-weight: 400\">Dado que la clave es una expresi\u00f3n generalizada, dispone de flexibilidad para aplicar l\u00f3gica y procesamiento adicionales a los datos antes de indexarlos. Por ejemplo, puede crear una indexaci\u00f3n funcional en los elementos de cada matriz. Dado que se est\u00e1 haciendo referencia a campos individuales del objeto o elemento dentro de la matriz, la expresi\u00f3n <a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-language-reference\/createindex.html\">creaci\u00f3n de \u00edndices<\/a>, el tama\u00f1o y la b\u00fasqueda son eficientes. El \u00edndice anterior s\u00f3lo almacena los valores distintos dentro de una matriz. Para almacenar todos los elementos de una matriz en un \u00edndice, utilice el modificador DISTINCT en la expresi\u00f3n.<\/span><\/p>\n<p><span class=\"font-size:17 line-height:20 lang:mysql decode:true crayon-inline\">CREATE INDEX travel_sched ON `travel-sample`\u00a0(ALL DISTINCT ARRAY v.day FOR v IN schedule END) <\/span><\/p>\n<p><span style=\"font-weight: 400\">El \u00edndice de array se puede crear sobre valores est\u00e1ticos (como arriba) o una expresi\u00f3n que devuelva un array. <\/span><a href=\"https:\/\/developer.couchbase.com\/documentation\/server\/current\/n1ql\/n1ql-language-reference\/tokenfun.html\"><span style=\"font-weight: 400\">TOKENS()<\/span><\/a><span style=\"font-weight: 400\"> son una de estas expresiones, devolviendo un array de tokens de un objeto. Puede crear un \u00edndice en esta matriz y buscar utilizando el \u00edndice.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Couchbase 5.0 hace m\u00e1s sencillo crear y emparejar los \u00edndices de array. Proporcionando el prefijo ALL ( o ALL DISTINCT) a la clave la convertir\u00e1 en una clave de array.<\/span><\/p>\n<pre class=\"font-size:17 line-height:20 wrap:true lang:mysql decode:true\">CREATE INDEX idx_cx6 \r\n  ON `travel-sample`(ALL TOKENS(public_likes)) \r\n  WHERE type = \u2018hotel\u2019;\r\n\r\nSELECT t.name, t.country, t.public_likes\r\n  FROM `travel-sample` t\r\n  WHERE t.type = 'hotel\u2019\r\n    AND ANY p IN TOKENS(public_likes) \r\n    SATISFIES p = 'Vallie' END;\r\n<\/pre>\n<p><span style=\"font-weight: 400\">Los \u00edndices de matrices tambi\u00e9n pueden crearse en elementos dentro de matrices de matrices. No hay l\u00edmite en el nivel de anidamiento de la expresi\u00f3n de la matriz. La expresi\u00f3n de la consulta debe coincidir con la expresi\u00f3n del \u00edndice.<\/span><\/p>\n<h3><b>7. \u00cdndice parcial<\/b><\/h3>\n<p><span style=\"font-weight: 400\">Hasta ahora, los \u00edndices que hemos creado crear\u00e1n \u00edndices sobre todo el bucket. Como el modelo de datos de Couchbase es JSON y los esquemas JSON son flexibles, un \u00edndice puede no contener entradas a documentos con claves de \u00edndice ausentes. Eso es lo esperado. A diferencia de los sistemas relacionales, donde cada tipo de fila est\u00e1 en una tabla distinta, los buckets de Couchbase pueden tener documentos de varios tipos. Normalmente, los clientes incluyen un campo de tipo para diferenciar los distintos tipos.<\/span><\/p>\n<pre class=\"font-size:17 line-height:20 lang:js decode:true\">{\r\n  \"airline\": {\r\n    \"callsign\": \"MILE-AIR\",\r\n    \"country\": \"United States\",\r\n    \"iata\": \"Q5\",\r\n    \"icao\": \"MLA\",\r\n    \"id\": 10,\r\n    \"name\": \"40-Mile Air\",\r\n    \"type\": \"airline\"\r\n      },\r\n  \"documentkey\": \"airline_10\"\r\n}\r\n<\/pre>\n<p><span style=\"font-weight: 400\">Si desea crear un \u00edndice de documentos de l\u00edneas a\u00e9reas, s\u00f3lo tiene que a\u00f1adir el campo de tipo para la cl\u00e1usula WHERE del \u00edndice.<\/span><\/p>\n<p><span class=\"font-size:17 line-height:20 lang:mysql decode:true crayon-inline\">CREATE INDEX travel_info ON `travel-sample`(name, id, icoo, iata) WHERE type = &#8216;airline&#8217;;<\/span><\/p>\n<p><span style=\"font-weight: 400\">Esto crear\u00e1 un \u00edndice s\u00f3lo en los documentos que tengan (tipo = 'compa\u00f1\u00eda a\u00e9rea'). En tus consultas, tendr\u00edas que incluir el filtro (tipo = 'compa\u00f1\u00eda a\u00e9rea') adem\u00e1s de otros filtros para que este \u00edndice cumpla los requisitos.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Puede utilizar predicados complejos en la cl\u00e1usula WHERE del \u00edndice. Varios casos de uso para explotar los \u00edndices parciales son:<\/span><\/p>\n<ol>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Partici\u00f3n de un \u00edndice grande en varios \u00edndices mediante la funci\u00f3n mod.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Partici\u00f3n de un \u00edndice grande en varios \u00edndices y colocaci\u00f3n de cada \u00edndice en nodos indexadores distintos.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Partici\u00f3n del \u00edndice en funci\u00f3n de una lista de valores. Por ejemplo, puede tener un \u00edndice para cada estado.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Simulando la partici\u00f3n del rango del \u00edndice a trav\u00e9s de un filtro de rango en la cl\u00e1usula WHERE. Una cosa a recordar es que las consultas N1QL de Couchbase usar\u00e1n un \u00edndice particionado por bloque de consulta. Usa UNION ALL para que una consulta explote m\u00faltiples \u00edndices particionados en una sola consulta.<\/span><\/li>\n<\/ol>\n<h3><b>8. \u00cdndice adaptativo<\/b><\/h3>\n<p><span style=\"font-weight: 400\">Un \u00edndice adaptativo crea un \u00edndice \u00fanico en todo el documento o conjunto de campos de un documento. Se trata de un \u00edndice de forma o matriz que utiliza el par {\"clave\": valor} como clave \u00fanica del \u00edndice. El prop\u00f3sito es evitar la pesadilla de una consulta que tiene que coincidir con las claves principales del \u00edndice en los \u00edndices tradicionales.<\/span><\/p>\n<p><span style=\"font-weight: 400\">El \u00edndice adaptativo tiene dos ventajas:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Se pueden evaluar m\u00faltiples predicados en el espacio de claves utilizando diferentes secciones del mismo \u00edndice.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Evite crear varios \u00edndices s\u00f3lo para reordenar las claves del \u00edndice.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Evite el orden de las claves de \u00edndice.<\/span><\/li>\n<\/ul>\n<p>Por ejemplo:<\/p>\n<pre class=\"font-size:17 line-height:20 wrap:true lang:mysql decode:true\">CREATE INDEX `ai_self`\r\n  ON `travel-sample`(DISTINCT PAIRS(ai_self))\r\n  WHERE type = \"airport\";\r\n\r\n  EXPLAIN SELECT * FROM `travel-sample`\r\n  WHERE faa = \"SFO\" \r\n    AND `type` = \"airport\";\r\n\r\n{\r\n  \"#operator\": \"IntersectScan\",\r\n  \"scans\": [\r\n    {\r\n      \"#operator\": \"IndexScan2\",\r\n      \"index\": \"ai_self\",\r\n      \"index_id\": \"c564a55225d9244c\",\r\n      \"index_projection\": {\r\n        \"primary_key\": true\r\n      },\r\n      \"keyspace\": \"travel-sample\",\r\n      \"namespace\": \"default\",\r\n      \"spans\": [\r\n        {\r\n          \"exact\": true,\r\n          \"range\": [\r\n            {\r\n              \"high\": \"[\\\"faa\\\", \\\"SFO\\\"]\",\r\n              \"inclusion\": 3,\r\n              \"low\": \"[\\\"faa\\\", \\\"SFO\\\"]\"\r\n            }\r\n          ]\r\n        }\r\n      ],\r\n      \"using\": \"gsi\"\r\n    }\r\n   ...\r\n  ]\r\n}<\/pre>\n<p><span style=\"font-weight: 400\">El mismo \u00edndice puede utilizarse tambi\u00e9n para consultas con otros predicados. Esto reduce el n\u00famero de \u00edndices que tendr\u00edas que crear a medida que crece el documento.<\/span><\/p>\n<pre class=\"font-size:17 line-height:20 lang:mysql decode:true\">EXPLAIN SELECT * \r\n  FROM `travel-sample` \r\n  WHERE city = \"Seattle\" \r\n    AND `type` = \"airport\";\r\n<\/pre>\n<p><span style=\"font-weight: 400\">Consideraciones sobre su uso:<\/span><\/p>\n<ol>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Dado que cada campo de atributo tiene una entrada de \u00edndice, el tama\u00f1o de los \u00edndices puede ser enorme.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">El \u00edndice adaptativo es un \u00edndice de matriz. Est\u00e1 limitado por la restricci\u00f3n de los \u00edndices del array.<\/span><\/li>\n<\/ol>\n<p><span style=\"font-weight: 400\">Consulte la documentaci\u00f3n detallada sobre<\/span><a href=\"https:\/\/developer.couchbase.com\/documentation\/server\/5.0\/n1ql\/n1ql-language-reference\/adaptive-indexing.html#untitled1\"> <span style=\"font-weight: 400\">\u00edndice adaptativo<\/span><\/a><span style=\"font-weight: 400\"> en la documentaci\u00f3n de Couchbase.<\/span><\/p>\n<h3><b>9. \u00cdndice de duplicados<\/b><\/h3>\n<p><span style=\"font-weight: 400\">Esto no es realmente un tipo especial de \u00edndice, sino una caracter\u00edstica de la indexaci\u00f3n de Couchbase. Puedes crear \u00edndices duplicados con nombres distintos.<\/span><\/p>\n<pre class=\"font-size:17 line-height:20 wrap:true lang:mysql decode:true\">CREATE INDEX i1 \r\n  ON `travel-sample`(LOWER(name),id, icoo) \r\n  WHERE type = \u2018airline\u2019;\r\n\r\nCREATE INDEX i2 \r\n  ON `travel-sample`(LOWER(name),id, icoo) \r\n  WHERE type = \u2018airline\u2019;\r\n\r\nCREATE INDEX i3 \r\n  ON `travel-sample`(LOWER(name),id, icoo) \r\n  WHERE type = \u2018airline\u2019;<\/pre>\n<p><span style=\"font-weight: 400\">Los tres \u00edndices tienen claves id\u00e9nticas, cl\u00e1usula WHERE id\u00e9ntica; la \u00fanica diferencia es el nombre de los \u00edndices. Puede elegir su ubicaci\u00f3n f\u00edsica mediante la cl\u00e1usula WITH de CREATE INDEX. Durante la optimizaci\u00f3n de la consulta, \u00e9sta elegir\u00e1 uno de los nombres. Lo ver\u00e1 en su plan. Durante la ejecuci\u00f3n de la consulta, estos \u00edndices se utilizan de forma rotatoria para distribuir la carga. Esto proporciona escalabilidad, escalabilidad multidimensional, rendimiento y alta disponibilidad. No est\u00e1 nada mal.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Couchbase 5.0 hace el \u00edndice duplicado M\u00c1S SENCILLO. En lugar de crear m\u00faltiples \u00edndices con nombres distintos, puedes simplemente especificar el n\u00famero de \u00edndices de r\u00e9plica que necesitas.<\/span><\/p>\n<pre class=\"wrap:true lang:mysql decode:true\">CREATE INDEX i1 \r\n  ON `travel-sample`(LOWER(name),id, icoo) \r\n  WHERE type = \u2018airline\u2019 \r\n  WITH {\"num_replica\" : 2 };\r\n<\/pre>\n<p><span style=\"font-weight: 400\">Esto crear\u00e1 2 copias adicionales del \u00edndice adem\u00e1s del \u00edndice i1. Las funciones de equilibrio de carga y HA son las mismas que un \u00edndice equivalente.<\/span><\/p>\n<p><b>10. \u00cdndice de cobertura<\/b><\/p>\n<p><span style=\"font-weight: 400\">La selecci\u00f3n del \u00edndice para una consulta depende \u00fanicamente de los filtros de la cl\u00e1usula WHERE de la consulta. Una vez hecha la selecci\u00f3n del \u00edndice, el motor analiza la consulta para ver si puede responderse utilizando s\u00f3lo los datos del \u00edndice. En caso afirmativo, el motor de consulta omite la recuperaci\u00f3n del documento completo. Se trata de una optimizaci\u00f3n del rendimiento que hay que tener en cuenta al dise\u00f1ar los \u00edndices.<\/span><\/p>\n<p><b>\u00a1Todos juntos ya!<\/b><\/p>\n<p><span style=\"font-weight: 400\">Vamos a crear un \u00edndice de matriz funcional compuesta particionada.<\/span><\/p>\n<pre class=\"font-size:17 line-height:20 wrap:true lang:mysql decode:true\">CREATE INDEX travel_all ON `travel-sample`(\r\n  iata,\r\n  LOWER(name),\r\n  UPPER(callsign),\r\n  ALL DISTINCT ARRAY p.model FOR p IN jets END),\r\n  TO_NUMBER(rating),\r\n  meta().id\r\n)\r\nWHERE LOWER(country) = \"united states\" AND type = \"airline\"\r\nWITH {\"num_replica\" : 2}<\/pre>\n<h2><strong>Reglas para crear los \u00edndices.<\/strong><\/h2>\n<p>Hasta ahora, hemos visto los tipos de \u00edndices. Veamos ahora c\u00f3mo dise\u00f1ar los \u00edndices para tu carga de trabajo.<\/p>\n<h3><span style=\"font-weight: 800\">Regla #1: UTILIZAR CLAVES<\/span><\/h3>\n<p><span style=\"font-weight: 400\">En Couchbase, cada documento de un bucket tiene una clave \u00fanica generada por el usuario. Los documentos se distribuyen entre los distintos nodos mediante el hash de esta clave (nosotros utilizamos <\/span><a href=\"https:\/\/developer.couchbase.com\/documentation\/server\/current\/architecture\/core-data-access-vbuckets-bucket-partition.html\"><span style=\"font-weight: 400\">hashing coherente<\/span><\/a><span style=\"font-weight: 400\">). Cuando tenga la clave del documento, puede obtener los documentos directamente de las aplicaciones (a trav\u00e9s de SDK). Incluso cuando se tienen las claves de los documentos, es posible que se desee hacer la obtenci\u00f3n y hacer alg\u00fan post-procesamiento a trav\u00e9s de N1QL. Es entonces cuando se utiliza el m\u00e9todo USE KEYS.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-4207 aligncenter\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/11\/Screen-Shot-2017-11-06-at-5.47.49-PM-300x227.png\" alt=\"\" width=\"300\" height=\"227\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/11\/Screen-Shot-2017-11-06-at-5.47.49-PM-300x227.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/11\/Screen-Shot-2017-11-06-at-5.47.49-PM-20x15.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/11\/Screen-Shot-2017-11-06-at-5.47.49-PM.png 368w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>Por ejemplo:<\/p>\n<pre class=\"font-size:17 line-height:20 wrap:true lang:mysql decode:true\">SELECT name, address\r\nFROM `travel-sample` h USE KEYS [\r\n  \"hotel_10025\",\r\n  \"hotel_10026\",\r\n  \"hotel_10063\",\r\n  \"hotel_10064\",\r\n  \"hotel_10138\",\r\n  \"hotel_10142\",\r\n  \"hotel_10158\",\r\n  \"hotel_10159\",\r\n  \"hotel_10160\",\r\n  \"hotel_10161\",\r\n  \"hotel_10180\",\r\n  \"hotel_10289\",\r\n  \"hotel_10290\",\r\n  \"hotel_10291\",\r\n  \"hotel_1072\",\r\n  \"hotel_10848\",\r\n  \"hotel_10849\",\r\n  \"hotel_10850\",\r\n  \"hotel_10851\",\r\n  \"hotel_10904\"\r\n]\r\nWHERE  h.country = \"United Kingdom\"\r\nAND ARRAY_LENGTH(public_likes) &gt; 3;\r\n<\/pre>\n<p><span style=\"font-weight: 400\">El m\u00e9todo de acceso USE KEYS puede utilizarse incluso cuando se realizan uniones. He aqu\u00ed un ejemplo:<\/span><\/p>\n<p><span class=\"font-size:17 line-height:20 lang:mysql decode:true crayon-inline\">SELECT * FROM ORDERS o USE KEYS [&#8220;ord::382&#8221;] INNER JOIN CUSTOMER c ON KEYS o.id; <\/span><\/p>\n<p><span style=\"font-weight: 400\">En Couchbsae 5.0, los \u00edndices s\u00f3lo se utilizan para procesar el primer espacio clave (bucket) de cada cl\u00e1usula FROM. Los espacios clave posteriores se procesan mediante la obtenci\u00f3n directa del documento.<\/span><\/p>\n<p><span class=\"font-size:17 line-height:20 lang:mysql decode:true crayon-inline\">SELECT * FROM ORDERS o INNER JOIN CUSTOMER c ON KEYS o.id\u00a0WHERE o.state = &#8220;CA&#8221;; <\/span><\/p>\n<p><span style=\"font-weight: 400\">En esta sentencia, procesamos el espacio de claves ORDERS a trav\u00e9s de un \u00edndice sobre (estado) si est\u00e1 disponible. En caso contrario, utilizamos el \u00edndice primario para escanear ORDERS. A continuaci\u00f3n, obtenemos los documentos de CLIENTES que coinciden con el identificador del documento de PEDIDOS.<\/span><\/p>\n<p><span style=\"font-weight: 800\">Norma #2: UTILIZAR \u00cdNDICE DE COBERTURA\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400\">Ya hemos hablado de los tipos de \u00edndice. El \u00edndice correcto sirve para dos cosas:<\/span><\/p>\n<ol>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Reducir el conjunto de trabajo de la consulta para acelerar su rendimiento<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Almacenar y proporcionar datos adicionales incluso.<\/span><\/li>\n<\/ol>\n<p><span style=\"font-weight: 400\">Cuando una consulta puede responderse completamente con los datos almacenados en el \u00edndice, se dice que la consulta es <\/span><i><span style=\"font-weight: 400\">cubierta <\/span><\/i><span style=\"font-weight: 400\">por el <\/span><i><span style=\"font-weight: 400\">\u00edndice de cobertura. <\/span><\/i><span style=\"font-weight: 400\">Debe intentar que la mayor\u00eda de sus consultas, si no todas, est\u00e9n cubiertas. Esto reducir\u00e1 la carga de procesamiento en el servicio de consulta, reducir la obtenci\u00f3n adicional del servicio de datos.<\/span><\/p>\n<p><span style=\"font-weight: 400\">La selecci\u00f3n del \u00edndice se sigue realizando en funci\u00f3n de los predicados de la consulta. Una vez realizada la selecci\u00f3n del \u00edndice, el optimizador evaluar\u00e1 si el \u00edndice contiene todos los atributos necesarios para la consulta y crear\u00e1 un acceso cubierto a la ruta del \u00edndice.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-4206\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/11\/Screen-Shot-2017-11-06-at-6.04.08-PM-300x226.png\" alt=\"\" width=\"300\" height=\"226\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/11\/Screen-Shot-2017-11-06-at-6.04.08-PM-300x226.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/11\/Screen-Shot-2017-11-06-at-6.04.08-PM-20x15.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/11\/Screen-Shot-2017-11-06-at-6.04.08-PM.png 366w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>Ejemplos:<\/p>\n<pre class=\"font-size:17 line-height:20 wrap:true lang:mysql decode:true\">CREATE INDEX idx_cx3 \r\n  ON CUSTOMER(state, city, name.lastname) \r\n  WHERE status = 'premium';\r\n\r\n\/* The query below won\u2019t be covered since you said: SELECT * *\/\r\nSELECT * \r\n  FROM CUSTOMER\r\n  WHERE state = 'CA\u2019 \r\n    AND status = 'premium';\r\n\r\n\/* The index has all three fields required by the query. *\/\r\n\/* Query will be covered, as shown in the explain plan. *\/\r\n\r\nSELECT status, state, city \r\n  FROM CUSTOMER\r\n  WHERE state = 'CA' \r\n    AND status = 'premium';\r\n\r\n{\r\n  \"#operator\": \"IndexScan2\",\r\n  \"covers\": [\r\n    \"cover ((`CUSTOMER`.`state`))\",\r\n    \"cover ((`CUSTOMER`.`city`))\",\r\n    \"cover (((`CUSTOMER`.`name`).`lastname`))\",\r\n    \"cover ((meta(`CUSTOMER`).`id`))\"\r\n  ],\r\n  \"filter_covers\": {\r\n    \"cover ((`CUSTOMER`.`status`))\": \"premium\"\r\n  },\r\n  \"index\": \"idx_cx3\",\r\n  \"index_id\": \"18f8209144215971\",\r\n  \"index_projection\": {\r\n  \"entry_keys\": [\r\n    0,\r\n    1\r\n  ]\r\n}\r\n<\/pre>\n<p><span style=\"font-weight: 400\">Observe que el campo status de la cl\u00e1usula WHERE del \u00edndice (status = 'premium') tambi\u00e9n est\u00e1 cubierto. Sabemos que todos los documentos del \u00edndice tienen un campo llamado estado con el valor \"premium\". Podemos simplemente proyectar este valor. El campo \"Filter_covers\" de la explicaci\u00f3n muestra esta informaci\u00f3n.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Mientras el \u00edndice tenga el campo, una consulta puede realizar filtrados adicionales, uniones, agregaci\u00f3n, paginaci\u00f3n despu\u00e9s de obtener los datos del indexador sin obtener el documento completo.<\/span><\/p>\n<p><span style=\"font-weight: 800\">Regla #3: UTILIZAR LA REPLICACI\u00d3N DE \u00cdNDICES <\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-4205\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/11\/Screen-Shot-2017-11-07-at-9.34.33-AM-300x112.png\" alt=\"\" width=\"567\" height=\"211\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/11\/Screen-Shot-2017-11-07-at-9.34.33-AM-300x112.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/11\/Screen-Shot-2017-11-07-at-9.34.33-AM-20x7.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/11\/Screen-Shot-2017-11-07-at-9.34.33-AM.png 714w\" sizes=\"auto, (max-width: 567px) 100vw, 567px\" \/><\/p>\n<p><span style=\"font-weight: 400\">En un cluster de Couchbase, tienes m\u00faltiples servicios de \u00edndices. Antes de Couchbase 5.0, pod\u00edas crear manualmente \u00edndices de r\u00e9plica (equivale) para mejorar el rendimiento, el equilibrio de carga y la alta disponibilidad.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Antes de la 5.0:<\/span><\/p>\n<pre class=\"font-size:17 line-height:20 wrap:true lang:mysql decode:true\">CREATE INDEX idx1 \r\n  ON CUSTOMER(state, city, name.lastname) \r\n  WHERE status = 'premium';\r\nCREATE INDEX idx2 \r\n  ON CUSTOMER(state, city, name.lastname) \r\n  WHERE status = 'premium';\r\nCREATE INDEX idx3 \r\n  ON CUSTOMER(state, city, name.lastname) \r\n  WHERE status = 'premium';\r\n<\/pre>\n<p><span style=\"font-weight: 400\">Reconocemos la equivalencia de estos tres \u00edndices porque las expresiones clave y la cl\u00e1usula WHERE son <\/span><b>exactamente<\/b><span style=\"font-weight: 400\"> lo mismo.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Durante la fase de optimizaci\u00f3n de la consulta, el motor N1QL elige uno de los tres \u00edndices para el escaneo de \u00edndices (suponiendo que se cumplan otros requisitos) para crear el plan de consulta. Durante la ejecuci\u00f3n de la consulta, \u00e9sta prepara el paquete de escaneo y env\u00eda una solicitud de escaneo de \u00edndice. Durante este proceso, bas\u00e1ndonos en las estad\u00edsticas de carga, enviamos la petici\u00f3n a uno de ellos. La idea es que, con el tiempo, cada uno de ellos tenga una carga similar.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Este proceso de creaci\u00f3n de \u00edndices r\u00e9plica (\u00edndices equivalentes) se facilita con un simple par\u00e1metro.<\/span><\/p>\n<pre class=\"font-size:17 line-height:20 wrap:true lang:mysql decode:true\">CREATE INDEX idx1 \r\n  ON CUSTOMER(state, city, name.lastname)\r\n  WHERE status = 'premium' \r\n  WITH { \"num_replica\":2 };<\/pre>\n<p><span style=\"font-weight: 400\">Es lo mismo que crear tres \u00edndices distintos pero equivalentes.<\/span><\/p>\n<p><span style=\"font-weight: 800\">Regla #4: INDEXAR POR CARGA DE TRABAJO, NO POR BUCKET\/KEYSPACE<\/span><\/p>\n<p><span style=\"font-weight: 400\">Considere toda la carga de trabajo de la aplicaci\u00f3n y los acuerdos de nivel de servicio (SLA) para cada una de las consultas. Las consultas que tengan requisitos de latencia de milisegundos con un alto rendimiento requerir\u00e1n \u00edndices personalizados y r\u00e9plicas, mientras que otras podr\u00edan compartir \u00edndices. <\/span><\/p>\n<p><span style=\"font-weight: 400\">Puede haber espacios de claves en los que simplemente se realicen operaciones set &amp; get o en los que se puedan realizar consultas con USE KEYS. Estos espacios de claves no necesitar\u00e1n \u00edndices.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Analice las consultas para encontrar los predicados comunes, proyecciones de un espacio de claves. Puede optimizar el n\u00famero de \u00edndices bas\u00e1ndose en los predicados comunes. Si una de sus consultas no tiene un predicado en la clave o claves principales, vea si a\u00f1adir (campo NO FALTA) tiene sentido para que el \u00edndice pueda ser compartido.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Est\u00e1 bien tener un \u00edndice primario mientras desarrollas tu aplicaci\u00f3n o consultas. Pero, antes de realizar pruebas, cree los \u00edndices adecuados y elimine el \u00edndice primario de su sistema, a menos que su aplicaci\u00f3n utilice los casos descritos en la secci\u00f3n \"\u00cdndice primario\". Si tienes un \u00edndice primario en producci\u00f3n y las consultas acaban haciendo un escaneo primario completo con un span completo en el \u00edndice, te est\u00e1s buscando problemas. En Couchbase, el \u00edndice primario indexa todos los documentos del bucket.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Cada \u00edndice secundario en Couchbase deber\u00eda tener una cl\u00e1usula WHERE, con al menos una condici\u00f3n sobre el tipo de documento. Esto no lo impone el sistema, pero es un buen dise\u00f1o.<\/span><\/p>\n<pre class=\"font-size:17 line-height:20 wrap:true lang:mysql decode:true\">CREATE INDEX def_route_src_dst \r\n ON `travel-sample` (`sourceairport`, `destinationairport`) \r\n WHERE (`type` = \"route\");\r\n<\/pre>\n<p><span style=\"font-weight: 400\">Crear los \u00edndices adecuados es una de las mejores pr\u00e1cticas para optimizar el rendimiento. Esto no es lo \u00fanico que hay que hacer para obtener el mejor rendimiento. La configuraci\u00f3n del cl\u00faster, el ajuste, la configuraci\u00f3n del SDK y el uso de sentencias preparadas desempe\u00f1an un papel importante.<\/span><\/p>\n<p><span style=\"font-weight: 800\">Regla #5: INDEXAR POR PREDICADO, NO POR PROYECTO<\/span><\/p>\n<p><span style=\"font-weight: 400\">Parece una regla obvia. Pero de vez en cuando me encuentro con gente que comete este error.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Considere la consulta:<\/span><\/p>\n<pre class=\"font-size:17 line-height:20 wrap:true lang:mysql decode:true\">SELECT city, state, status \r\n  FROM CUSTOMER \r\n  WHERE state = 'CA' \r\n    AND status = 'premium';\r\n<\/pre>\n<p><span style=\"font-weight: 400\">La consulta puede utilizar cualquiera de los siguientes \u00edndices:<\/span><\/p>\n<pre class=\"font-size:17 line-height:20 wrap:true lang:mysql decode:true\">Create index i1 on CUSTOMER(state);\r\nCreate index i2 on CUSTOMER(status);\r\nCreate index i3 on CUSTOMER(state, status);\r\nCreate index i4 on CUSTOMER(status, state);\r\nCreate index i5 on CUSTOMER(state) WHERE status = \u201cpremium\u201d;\r\nCreate index i6 on CUSTOMER(status) WHERE status = \u201cCA\u201d;<\/pre>\n<p>Para que el \u00edndice cubra completamente la consulta, basta con a\u00f1adir el campo ciudad al \u00edndice 3-6.<\/p>\n<p>Sin embargo, si tiene un \u00edndice con la ciudad como clave principal, el optimizador no lo detectar\u00e1.<\/p>\n<pre class=\"font-size:17 line-height:20 lang:mysql decode:true\">Create index i7 O\r\n  ON CUSTOMER(city, state) \r\n  WHERE status = \u201cpremium\u201d;\r\n<\/pre>\n<p><span style=\"font-weight: 400\">Consulte el art\u00edculo detallado sobre c\u00f3mo funciona la exploraci\u00f3n de \u00edndices en varios escenarios para optimizar el \u00edndice: <\/span><a href=\"https:\/\/dzone.com\/articles\/understanding-index-scans-in-couchbase-50-n1ql-que\"><span style=\"font-weight: 400\">https:\/\/dzone.com\/articles\/understanding-index-scans-in-couchbase-50-n1ql-que<\/span><\/a><\/p>\n<p><span style=\"font-weight: 800\">Norma #6: A\u00d1ADIR \u00cdNDICES PARA CUMPLIR LOS ANS <\/span><\/p>\n<p><span style=\"font-weight: 400\">Para las bases de datos relacionales, lo m\u00e1s importante eran tres cosas: rendimiento, rendimiento y rendimiento.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Para las bases de datos NoSQL, lo m\u00e1s importante son tres cosas: rendimiento a escala, rendimiento a escala, rendimiento a escala.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Una cosa son tus consultas ejecutando pruebas b\u00e1sicas de rendimiento en tu port\u00e1til, y otra cosa es ejecutar las consultas de alto rendimiento y baja latencia en el cl\u00faster. Afortunadamente, en Couchbase es f\u00e1cil identificar y escalar los recursos cuello de botella de forma independiente, gracias al escalado multidimensional. Cada uno de los servicios en Couchbase se abstrae en servicios distintos: datos, \u00edndice, consulta. La consola de Couchbase tiene estad\u00edsticas de cada uno de los servicios de forma independiente. <\/span><\/p>\n<p><span style=\"font-weight: 400\">Una vez creados los \u00edndices para sus consultas y optimizados los \u00edndices para la carga de trabajo, puede a\u00f1adir \u00edndices de r\u00e9plica (equivalentes) adicionales para mejorar la latencia, ya que equilibramos la carga de los escaneos entre los \u00edndices de r\u00e9plica. <\/span><\/p>\n<p><span style=\"font-weight: 800\">Regla #7: \u00cdNDICE PARA EVITAR LA CLASIFICACI\u00d3N<\/span><\/p>\n<p><span style=\"font-weight: 400\">El \u00edndice ya tiene los datos en el orden de las claves del \u00edndice. Tras la exploraci\u00f3n, el \u00edndice devuelve los resultados en el orden de las claves del \u00edndice.<\/span><\/p>\n<pre class=\"font-size:17 line-height:20 wrap:true lang:mysql decode:true\">CREATE INDEX idx3 \r\n  ON `travel-sample`(state, city, name.lastname)\r\n  WHERE status = 'premium';<\/pre>\n<p><span style=\"font-weight: 400\">Los datos se almacenan y devuelven en el orden: estado, ciudad, nombre.apellido. Por lo tanto, si tienes una consulta que espera los datos en el orden estado, ciudad, nombre.apellido, un \u00edndice te ayudar\u00e1 a evitar la ordenaci\u00f3n.<\/span><\/p>\n<p><span style=\"font-weight: 400\">En este ejemplo, los resultados se ordenan por nombre.apellido, la tercera clave del \u00edndice. Por lo tanto, es necesario ordenar el conjunto de resultados por nombre.apellido. Explain le indicar\u00e1 si el plan requiere esta ordenaci\u00f3n.<\/span><\/p>\n<pre class=\"font-size:17 line-height:20 wrap:true lang:mysql decode:true\">EXPLAIN SELECT state, city, name.lastname \r\n  FROM `travel-sample`\r\n  WHERE status = \u2018premium\u2019 \r\n    AND state = \u2018CA\u2019 \r\n    AND city LIKE \u2018san%\u2019\r\n  ORDER BY name.lastname;\r\n\r\n{\r\n  \"plan\": {\r\n    \"#operator\": \"Sequence\",\r\n    \"~children\": [\r\n      {\r\n        \"#operator\": \"Sequence\",\r\n        \"~children\": [\r\n          {\r\n            \"#operator\": \"IndexScan2\",\r\n            \"covers\": [\r\n              \"cover ((`travel-sample`.`state`))\",\r\n              \"cover ((`travel-sample`.`city`))\",\r\n              \"cover (((`travel-sample`.`name`).`lastname`))\",\r\n              \"cover ((meta(`travel-sample`).`id`))\"\r\n            ],\r\n            \"filter_covers\": {\r\n              \"cover ((`travel-sample`.`status`))\": \"premium\"\r\n            },\r\n            \"index\": \"idx3\",\r\n            \"index_id\": \"19a5aed899d281fe\",\r\n            \"index_projection\": {\r\n              \"entry_keys\": [\r\n                0,\r\n                1,\r\n                2\r\n              ]\r\n            },\r\n            \"keyspace\": \"travel-sample\",\r\n            \"namespace\": \"default\",\r\n            \"spans\": [\r\n              {\r\n                \"exact\": true,\r\n                \"range\": [\r\n                  {\r\n                    \"high\": \"\\\"CA\\\"\",\r\n                    \"inclusion\": 3,\r\n                    \"low\": \"\\\"CA\\\"\"\r\n                  },\r\n                  {\r\n                    \"high\": \"\\\"sao\\\"\",\r\n                    \"inclusion\": 1,\r\n                    \"low\": \"\\\"san\\\"\"\r\n                  }\r\n                ]\r\n              }\r\n            ],\r\n            \"using\": \"gsi\"\r\n          },\r\n          {\r\n            \"#operator\": \"Parallel\",\r\n            \"~child\": {\r\n              \"#operator\": \"Sequence\",\r\n              \"~children\": [\r\n                {\r\n                  \"#operator\": \"Filter\",\r\n                  \"condition\": \"(((cover ((`travel-sample`.`status`)) = \\\"premium\\\") and (cover ((`travel-sample`.`state`)) = \\\"CA\\\")) and (cover ((`travel-sample`.`city`)) like \\\"san%\\\"))\"\r\n                },\r\n                {\r\n                  \"#operator\": \"InitialProject\",\r\n                  \"result_terms\": [\r\n                    {\r\n                      \"expr\": \"cover ((`travel-sample`.`state`))\"\r\n                    },\r\n                    {\r\n                      \"expr\": \"cover ((`travel-sample`.`city`))\"\r\n                    },\r\n                    {\r\n                      \"expr\": \"cover (((`travel-sample`.`name`).`lastname`))\"\r\n                    }\r\n                  ]\r\n                }\r\n              ]\r\n            }\r\n          }\r\n        ]\r\n      },\r\n      {\r\n        \"#operator\": \"Order\",\r\n        \"sort_terms\": [\r\n          {\r\n            \"expr\": \"cover (((`travel-sample`.`name`).`lastname`))\"\r\n          }\r\n        ]\r\n      },\r\n      {\r\n        \"#operator\": \"FinalProject\"\r\n      }\r\n    ]\r\n  },\r\n  \"text\": \"SELECT state, city, name.lastname \\nFROM `travel-sample`\\nWHERE status = 'premium' AND state = 'CA' AND city LIKE 'san%'\\nORDER BY name.lastname;\"\r\n}\r\n<\/pre>\n<p><span style=\"font-weight: 400\">La consulta siguiente tiene la correspondencia perfecta para las claves del \u00edndice.  Por lo tanto, la ordenaci\u00f3n es innecesaria.  En la salida explain, falta el operador de ordenaci\u00f3n.<\/span><\/p>\n<pre class=\"font-size:17 line-height:20 wrap:true lang:mysql decode:true\">EXPLAIN SELECT state, city, name.lastname \r\nFROM `travel-sample`\r\nWHERE status = \u2018premium\u2019 \r\n  AND state = \u2018CA\u2019 \r\n  AND city LIKE \u2018san%\u2019\r\nORDER BY state, city, name.lastname;\r\n\r\n\r\n{\r\n  \"plan\": {\r\n    \"#operator\": \"Sequence\",\r\n    \"~children\": [\r\n      {\r\n        \"#operator\": \"Sequence\",\r\n        \"~children\": [\r\n          {\r\n            \"#operator\": \"IndexScan2\",\r\n            \"covers\": [\r\n              \"cover ((`travel-sample`.`state`))\",\r\n              \"cover ((`travel-sample`.`city`))\",\r\n              \"cover (((`travel-sample`.`name`).`lastname`))\",\r\n              \"cover ((meta(`travel-sample`).`id`))\"\r\n            ],\r\n            \"filter_covers\": {\r\n              \"cover ((`travel-sample`.`status`))\": \"premium\"\r\n            },\r\n            \"index\": \"idx3\",\r\n            \"index_id\": \"19a5aed899d281fe\",\r\n            \"index_projection\": {\r\n              \"entry_keys\": [\r\n                0,\r\n                1,\r\n                2\r\n              ]\r\n            },\r\n            \"keyspace\": \"travel-sample\",\r\n            \"namespace\": \"default\",\r\n            \"spans\": [\r\n              {\r\n                \"exact\": true,\r\n                \"range\": [\r\n                  {\r\n                    \"high\": \"\\\"CA\\\"\",\r\n                    \"inclusion\": 3,\r\n                    \"low\": \"\\\"CA\\\"\"\r\n                  },\r\n                  {\r\n                    \"high\": \"\\\"sao\\\"\",\r\n                    \"inclusion\": 1,\r\n                    \"low\": \"\\\"san\\\"\"\r\n                  }\r\n                ]\r\n              }\r\n            ],\r\n            \"using\": \"gsi\"\r\n          },\r\n          {\r\n            \"#operator\": \"Parallel\",\r\n            \"maxParallelism\": 1,\r\n            \"~child\": {\r\n              \"#operator\": \"Sequence\",\r\n              \"~children\": [\r\n                {\r\n                  \"#operator\": \"Filter\",\r\n                  \"condition\": \"(((cover ((`travel-sample`.`status`)) = \\\"premium\\\") and (cover ((`travel-sample`.`state`)) = \\\"CA\\\")) and (cover ((`travel-sample`.`city`)) like \\\"san%\\\"))\"\r\n                },\r\n                {\r\n                  \"#operator\": \"InitialProject\",\r\n                  \"result_terms\": [\r\n                    {\r\n                      \"expr\": \"cover ((`travel-sample`.`state`))\"\r\n                    },\r\n                    {\r\n                      \"expr\": \"cover ((`travel-sample`.`city`))\"\r\n                    },\r\n                    {\r\n                      \"expr\": \"cover (((`travel-sample`.`name`).`lastname`))\"\r\n                    }\r\n                  ]\r\n                },\r\n                {\r\n                  \"#operator\": \"FinalProject\"\r\n                }\r\n              ]\r\n            }\r\n          }\r\n        ]\r\n      }\r\n    ]\r\n  },\r\n  \"text\": \"SELECT state, city, name.lastname \\nFROM `travel-sample`\\nWHERE status = 'premium' AND state = 'CA' AND city LIKE 'san%'\\nORDER BY state, city, name.lastname;\"\r\n}\r\n<\/pre>\n<p><span style=\"font-weight: 400\">Explotar el orden de clasificaci\u00f3n del \u00edndice puede no parecer importante hasta que se ve el caso de uso de la paginaci\u00f3n.  Cuando la consulta ha especificado OFFSET y LIMIT, se puede utilizar un \u00edndice para eliminar de forma eficiente los documentos que a la aplicaci\u00f3n no le interesan o no necesita.  V\u00e9ase el<\/span><a href=\"https:\/\/www.couchbase.com\/blog\/es\/optimizing-database-pagination-using-couchbase-n1ql\/\"><span style=\"font-weight: 400\"> art\u00edculo sobre paginaci\u00f3n para m\u00e1s detalles<\/span><\/a><span style=\"font-weight: 400\">.<\/span><\/p>\n<p><span style=\"font-weight: 400\">El optimizador N1QL primero selecciona el \u00edndice bas\u00e1ndose en los predicados de la consulta (filtros) y luego verifica si el \u00edndice puede cubrir todas las referencias de la consulta en proyecci\u00f3n y orden por.  Despu\u00e9s, el optimizador intenta eliminar la ordenaci\u00f3n y decidir sobre el pushdown de OFFSET y LIMIT.  La explicaci\u00f3n muestra si el OFFSET y el LIMIT fueron empujados a la exploraci\u00f3n del \u00edndice.<\/span><\/p>\n<pre class=\"font-size:17 line-height:30 lang:js decode:true\">\"keyspace\": \"travel-sample\",\r\n\"limit\": \"20\",\r\n\"namespace\": \"default\",\r\n\"offset\": \"100\",\r\n\"spans\": [\r\n  {\r\n    \"exact\": true,\r\n    \"range\": [\r\n      {\r\n        \"high\": \"\\\"CA\\\"\",\r\n        \"inclusion\": 3,\r\n        \"low\": \"\\\"CA\\\"\"\r\n      },\r\n      {\r\n        \"high\": \"\\\"sao\\\"\",\r\n        \"inclusion\": 1,\r\n        \"low\": \"\\\"san\\\"\"\r\n      }\r\n    ]\r\n  }\r\n]\r\n<\/pre>\n<p><span style=\"font-weight: 800\">Regla #8: N\u00famero de \u00edndices<\/span><\/p>\n<p><span style=\"font-weight: 400\">No hay l\u00edmite artificial en el n\u00famero de \u00edndices que puedes tener en el sistema. Si vas a crear un gran n\u00famero de \u00edndices en un bucket que tiene los datos, utiliza la opci\u00f3n de creaci\u00f3n diferida para que la transferencia de datos entre el servicio de datos y el servicio de \u00edndices sea eficiente.<\/span><\/p>\n<p><span style=\"font-weight: 800\">Regla #9: \u00cdndice durante INSERT, DELETE, UPDATE<\/span><\/p>\n<p><span style=\"font-weight: 400\">El \u00edndice se mantiene de forma as\u00edncrona. Sus actualizaciones de datos a trav\u00e9s de la API clave-valor o cualquier sentencia N1QL s\u00f3lo actualizan los documentos en el bucket.  El \u00edndice recibe la notificaci\u00f3n de los cambios a trav\u00e9s del flujo y aplica los cambios al \u00edndice. Esta es la secuencia de operaciones para una sentencia UPDATE. La sentencia utiliza el \u00edndice para calificar los documentos a actualizar; obtiene los documentos y los actualiza; luego escribe los documentos de vuelta y devuelve cualquier dato solicitado desde la sentencia UPDATE.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-4208\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/11\/Screen-Shot-2017-11-10-at-10.22.38-PM-300x153.png\" alt=\"\" width=\"735\" height=\"375\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/11\/Screen-Shot-2017-11-10-at-10.22.38-PM-300x153.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/11\/Screen-Shot-2017-11-10-at-10.22.38-PM-1024x522.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/11\/Screen-Shot-2017-11-10-at-10.22.38-PM-768x391.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/11\/Screen-Shot-2017-11-10-at-10.22.38-PM-1536x783.png 1536w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/11\/Screen-Shot-2017-11-10-at-10.22.38-PM-20x10.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/11\/Screen-Shot-2017-11-10-at-10.22.38-PM-1320x673.png 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/11\/Screen-Shot-2017-11-10-at-10.22.38-PM.png 1790w\" sizes=\"auto, (max-width: 735px) 100vw, 735px\" \/><\/p>\n<p><span style=\"font-weight: 800\">Regla #11: ORDEN DE CLAVE DE \u00cdNDICE Y TIPOS DE PREDICADO<\/span><\/p>\n<p><span style=\"font-weight: 400\">Las peticiones de escaneo del \u00edndice creadas por los usuarios de la consulta son las N primeras claves consecutivas del \u00edndice.  Por tanto, el orden de la clave del \u00edndice es importante. <\/span><\/p>\n<p><span style=\"font-weight: 400\">Consideremos una consulta con varios predicados:<\/span><\/p>\n<pre class=\"font-size:17 line-height:20 wrap:true lang:mysql decode:true\">SELECT cid, address FROM CUSTOMER\r\n  WHERE state = \u2018CA\u2019\r\n  AND type = \u2018premium\u2019\r\n  AND zipcode IN [29482, 29284, 29482, 28472]\r\n  AND salary &lt; 50000 AND age &gt; 45;<\/pre>\n<p><span style=\"font-weight: 400\">Se trata de reglas generales para el orden de las claves en el \u00edndice.  Las claves pueden ser atributos escalares m\u00e1s simples o expresiones que devuelven valores escalares: por ejemplo, UPPER(nombre.apellido).<\/span><\/p>\n<ol>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">La primera prioridad son las claves con predicados de igualdad. En esta consulta, es sobre estado y tipo. Cuando hay varios predicados del mismo tipo, elige cualquier combinaci\u00f3n.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">La segunda prioridad son las claves con predicados IN. En esta consulta, se trata del c\u00f3digo postal.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">La tercera prioridad es el predicado menor que (&lt;). En este caso, es sobre el salario.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">La cuarta prioridad son los predicados between. Esta consulta no tiene un predicado between.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">La quinta prioridad son los predicados mayor que (&gt;).  En esta consulta, es sobre la edad.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">La sexta prioridad son los predicados de array: ANY, o EVERY AND ANY, predicados despu\u00e9s de UNNEST.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Busque a\u00f1adir campos adicionales para que el \u00edndice cubra la consulta.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Despu\u00e9s de hacer este an\u00e1lisis, busque cualquier expresi\u00f3n que se pueda mover a la cl\u00e1usula WHERE.  Por ejemplo, en este caso, type = \"premium\" se puede mover porque el campo type es designado por los usuarios para identificar el tipo de clientes.<\/span><\/li>\n<\/ol>\n<p><span style=\"font-weight: 400\">Con esto, llegamos al siguiente \u00edndice.<\/span><\/p>\n<pre class=\"font-size:17 line-height:20 lang:mysql decode:true\">CREATE INDEX idx_order \r\n  ON CUSTOMER ( \r\n    state, zipcode, salary, age, address, cid\r\n  ) \r\n  WHERE type = \"premium\";<\/pre>\n<p><span style=\"font-weight: 800\">Regla #12: Saber leer EXPLAIN y PROFILING<\/span><\/p>\n<p><span style=\"font-weight: 400\">No importa cu\u00e1ntas reglas sigas, tendr\u00e1s que entender los planes de consulta y el perfil, monitorizar el sistema bajo carga y ajustarlo.  La capacidad de comprender y analizar el plan de consulta y la informaci\u00f3n de perfiles es la clave para ajustar una consulta y una carga de trabajo.  Hay dos buenos art\u00edculos sobre estos temas.  Rep\u00e1salos y prueba los ejemplos.\u00a0<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400\"><a href=\"https:\/\/dzone.com\/articles\/understanding-index-scans-in-couchbase-50-n1ql-que\"><span style=\"font-weight: 400\">https:\/\/dzone.com\/articles\/understanding-index-scans-in-couchbase-50-n1ql-que<\/span><\/a><\/li>\n<li style=\"font-weight: 400\"><a href=\"https:\/\/www.couchbase.com\/blog\/es\/profiling-monitoring-update-2\/\"><span style=\"font-weight: 400\">https:\/\/www.couchbase.com\/blog\/profiling-monitoring-update-2\/<\/span><\/a><\/li>\n<\/ul>\n<p><b>Referencias<\/b><\/p>\n<ul>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Nitro: A Fast, Scalable In-Memory Storage Engine for NoSQL Global Secondary Index:<\/span><a href=\"https:\/\/vldb2016.persistent.com\/industrial_track_papers.php\"> <span style=\"font-weight: 400\">https:\/\/vldb2016.persistent.com\/industrial_track_papers.php<\/span><\/a><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Couchbase: \u00a0<\/span><a href=\"https:\/\/www.couchbase.com\/blog\/es\/\"><span style=\"font-weight: 400\">https:\/\/www.couchbase.com<\/span><\/a><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Documentaci\u00f3n de Couchbase:<\/span> <a href=\"https:\/\/docs.couchbase.com\"><span style=\"font-weight: 400\">https:\/\/docs.couchbase.com<\/span><\/a><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">N1QL: Gu\u00eda pr\u00e1ctica: <\/span><a href=\"https:\/\/www.couchbase.com\/blog\/es\/n1ql-practical-guide-second-edition\/\"><span style=\"font-weight: 400\">https:\/\/www.couchbase.com\/blog\/n1ql-practical-guide-second-edition\/<\/span><\/a><\/li>\n<li>Asesor de \u00edndices: Reglas para la creaci\u00f3n de \u00edndices:\u00a0<a href=\"https:\/\/www.slideshare.net\/journalofinformix\/couchbase-n1ql-index-advisor\">https:\/\/www.slideshare.net\/journalofinformix\/couchbase-n1ql-index-advisor<\/a><\/li>\n<\/ul>","protected":false},"excerpt":{"rendered":"<p>Introduction There are three things important in database systems: performance, performance, performance. For NoSQL database systems, there are three important things: performance at scale, performance at scale, performance at scale. Understanding the index options, creating the right index, with the [&hellip;]<\/p>","protected":false},"author":55,"featured_media":4218,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1814,9417,1812],"tags":[1311,1505,1725,1854,2093,1506],"ppma_author":[8929],"class_list":["post-4204","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-application-design","category-performance","category-n1ql-query","tag-architecture","tag-index","tag-nosql-database","tag-profiling","tag-scale","tag-tuning"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.1 (Yoast SEO v26.1.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Right Index Option: How to Get the Right Performance<\/title>\n<meta name=\"description\" content=\"Understanding the index options, creating the right index, with the right keys, right order, and right expression is critical to query performance at scale.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/es\/create-right-index-get-right-performance\/\" \/>\n<meta property=\"og:locale\" content=\"es_MX\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Create the Right Index, Get the Right Performance.\" \/>\n<meta property=\"og:description\" content=\"Understanding the index options, creating the right index, with the right keys, right order, and right expression is critical to query performance at scale.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/es\/create-right-index-get-right-performance\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2017-11-12T22:08:59+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T03:20:14+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/11\/Screen-Shot-2017-11-12-at-10.48.03-PM.png\" \/>\n\t<meta property=\"og:image:width\" content=\"854\" \/>\n\t<meta property=\"og:image:height\" content=\"628\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Keshav Murthy\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@rkeshavmurthy\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Keshav Murthy\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"20 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/create-right-index-get-right-performance\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/create-right-index-get-right-performance\/\"},\"author\":{\"name\":\"Keshav Murthy\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c261644262bf98e146372fe647682636\"},\"headline\":\"Create the Right Index, Get the Right Performance.\",\"datePublished\":\"2017-11-12T22:08:59+00:00\",\"dateModified\":\"2025-06-14T03:20:14+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/create-right-index-get-right-performance\/\"},\"wordCount\":4279,\"commentCount\":5,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/create-right-index-get-right-performance\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/11\/Screen-Shot-2017-11-12-at-10.48.03-PM.png\",\"keywords\":[\"Architecture\",\"Index\",\"NoSQL Database\",\"profiling\",\"scale\",\"Tuning\"],\"articleSection\":[\"Application Design\",\"High Performance\",\"SQL++ \/ N1QL Query\"],\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/create-right-index-get-right-performance\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/create-right-index-get-right-performance\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/create-right-index-get-right-performance\/\",\"name\":\"Right Index Option: How to Get the Right Performance\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/create-right-index-get-right-performance\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/create-right-index-get-right-performance\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/11\/Screen-Shot-2017-11-12-at-10.48.03-PM.png\",\"datePublished\":\"2017-11-12T22:08:59+00:00\",\"dateModified\":\"2025-06-14T03:20:14+00:00\",\"description\":\"Understanding the index options, creating the right index, with the right keys, right order, and right expression is critical to query performance at scale.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/create-right-index-get-right-performance\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/create-right-index-get-right-performance\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/create-right-index-get-right-performance\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/11\/Screen-Shot-2017-11-12-at-10.48.03-PM.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/11\/Screen-Shot-2017-11-12-at-10.48.03-PM.png\",\"width\":854,\"height\":628},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/create-right-index-get-right-performance\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Create the Right Index, Get the Right Performance.\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"es\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c261644262bf98e146372fe647682636\",\"name\":\"Keshav Murthy\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/4e51d72fc07c662aa791316deafffac4\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/af74df754db27152971d0aed2f323ead5a1f9fe5afd0209af91e12e784451224?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/af74df754db27152971d0aed2f323ead5a1f9fe5afd0209af91e12e784451224?s=96&d=mm&r=g\",\"caption\":\"Keshav Murthy\"},\"description\":\"Keshav Murthy is a Vice President at Couchbase R&amp;D. Previously, he was at MapR, IBM, Informix, Sybase, with more than 20 years of experience in database design &amp; development. He lead the SQL and NoSQL R&amp;D team at IBM Informix. He has received two President's Club awards at Couchbase, two Outstanding Technical Achievement Awards at IBM. Keshav has a bachelor's degree in Computer Science and Engineering from the University of Mysore, India, holds eleven US patents and has four US patents pending.\",\"sameAs\":[\"https:\/\/blog.planetnosql.com\/\",\"https:\/\/x.com\/rkeshavmurthy\"],\"url\":\"https:\/\/www.couchbase.com\/blog\/es\/author\/keshav-murthy\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Right Index Option: How to Get the Right Performance","description":"Comprender las opciones de \u00edndice, crear el \u00edndice correcto, con las claves correctas, el orden correcto y la expresi\u00f3n correcta es fundamental para el rendimiento de las consultas a escala.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/es\/create-right-index-get-right-performance\/","og_locale":"es_MX","og_type":"article","og_title":"Create the Right Index, Get the Right Performance.","og_description":"Understanding the index options, creating the right index, with the right keys, right order, and right expression is critical to query performance at scale.","og_url":"https:\/\/www.couchbase.com\/blog\/es\/create-right-index-get-right-performance\/","og_site_name":"The Couchbase Blog","article_published_time":"2017-11-12T22:08:59+00:00","article_modified_time":"2025-06-14T03:20:14+00:00","og_image":[{"width":854,"height":628,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/11\/Screen-Shot-2017-11-12-at-10.48.03-PM.png","type":"image\/png"}],"author":"Keshav Murthy","twitter_card":"summary_large_image","twitter_creator":"@rkeshavmurthy","twitter_misc":{"Written by":"Keshav Murthy","Est. reading time":"20 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/create-right-index-get-right-performance\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/create-right-index-get-right-performance\/"},"author":{"name":"Keshav Murthy","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c261644262bf98e146372fe647682636"},"headline":"Create the Right Index, Get the Right Performance.","datePublished":"2017-11-12T22:08:59+00:00","dateModified":"2025-06-14T03:20:14+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/create-right-index-get-right-performance\/"},"wordCount":4279,"commentCount":5,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/create-right-index-get-right-performance\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/11\/Screen-Shot-2017-11-12-at-10.48.03-PM.png","keywords":["Architecture","Index","NoSQL Database","profiling","scale","Tuning"],"articleSection":["Application Design","High Performance","SQL++ \/ N1QL Query"],"inLanguage":"es","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/create-right-index-get-right-performance\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/create-right-index-get-right-performance\/","url":"https:\/\/www.couchbase.com\/blog\/create-right-index-get-right-performance\/","name":"Right Index Option: How to Get the Right Performance","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/create-right-index-get-right-performance\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/create-right-index-get-right-performance\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/11\/Screen-Shot-2017-11-12-at-10.48.03-PM.png","datePublished":"2017-11-12T22:08:59+00:00","dateModified":"2025-06-14T03:20:14+00:00","description":"Comprender las opciones de \u00edndice, crear el \u00edndice correcto, con las claves correctas, el orden correcto y la expresi\u00f3n correcta es fundamental para el rendimiento de las consultas a escala.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/create-right-index-get-right-performance\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/create-right-index-get-right-performance\/"]}]},{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/create-right-index-get-right-performance\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/11\/Screen-Shot-2017-11-12-at-10.48.03-PM.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/11\/Screen-Shot-2017-11-12-at-10.48.03-PM.png","width":854,"height":628},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/create-right-index-get-right-performance\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Create the Right Index, Get the Right Performance."}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"El blog de Couchbase","description":"Couchbase, la base de datos NoSQL","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"es"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"El blog de Couchbase","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c261644262bf98e146372fe647682636","name":"Keshav Murthy","image":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/4e51d72fc07c662aa791316deafffac4","url":"https:\/\/secure.gravatar.com\/avatar\/af74df754db27152971d0aed2f323ead5a1f9fe5afd0209af91e12e784451224?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/af74df754db27152971d0aed2f323ead5a1f9fe5afd0209af91e12e784451224?s=96&d=mm&r=g","caption":"Keshav Murthy"},"description":"Keshav Murthy es Vicepresidente de Couchbase R&amp;D. Anteriormente, estuvo en MapR, IBM, Informix, Sybase, con m\u00e1s de 20 a\u00f1os de experiencia en dise\u00f1o y desarrollo de bases de datos. Dirigi\u00f3 el equipo de I+D de SQL y NoSQL en IBM Informix. Ha recibido dos premios President's Club en Couchbase y dos premios Outstanding Technical Achievement en IBM. Keshav es licenciado en Inform\u00e1tica e Ingenier\u00eda por la Universidad de Mysore (India), es titular de once patentes estadounidenses y tiene cuatro pendientes.","sameAs":["https:\/\/blog.planetnosql.com\/","https:\/\/x.com\/rkeshavmurthy"],"url":"https:\/\/www.couchbase.com\/blog\/es\/author\/keshav-murthy\/"}]}},"authors":[{"term_id":8929,"user_id":55,"is_guest":0,"slug":"keshav-murthy","display_name":"Keshav Murthy","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/af74df754db27152971d0aed2f323ead5a1f9fe5afd0209af91e12e784451224?s=96&d=mm&r=g","author_category":"","last_name":"Murthy","first_name":"Keshav","job_title":"","user_url":"https:\/\/blog.planetnosql.com\/","description":"Keshav Murthy es Vicepresidente de Couchbase R&amp;D. Anteriormente, estuvo en MapR, IBM, Informix, Sybase, con m\u00e1s de 20 a\u00f1os de experiencia en dise\u00f1o y desarrollo de bases de datos. Dirigi\u00f3 el equipo de I+D de SQL y NoSQL en IBM Informix. Ha recibido dos premios President's Club en Couchbase y dos premios Outstanding Technical Achievement en IBM. Keshav es licenciado en Inform\u00e1tica e Ingenier\u00eda por la Universidad de Mysore (India), es titular de diez patentes estadounidenses y tiene tres pendientes."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/4204","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/users\/55"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/comments?post=4204"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/4204\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/media\/4218"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/media?parent=4204"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/categories?post=4204"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/tags?post=4204"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/ppma_author?post=4204"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}