¡Hurra! Acabamos de lanzar Servidor Couchbase 4.5 que trae una bolsa llena de maravillosas características y mejoras. Mi post anterior Aproveche al máximo sus matrices... con la indexación de matrices introdujo la funcionalidad de indexación de matrices. Esta entrada de blog incluye índices de matriz, soporte para más operadores como UNNEST, ALL, ANY AND EVERY etc.,
Cubrir índices de matrices
Índices de cobertura es una característica de rendimiento en N1QL, que mejora significativamente el rendimiento de la consulta al evitar viajes al servicio de datos para obtener cualquier documento. No existe una sintaxis especial para crear/utilizar índices de cobertura. Esta es una optimización automática activada en N1QL, cuando una consulta puede encontrar todos los datos requeridos en el índice mismo. Por lo tanto, los índices cubiertos son simplemente GSI normales. índices que se crean con todas las claves de índice que cubren los datos necesarios para una consulta.
Normalmente, los índices de matrices se crean con los elementos/atributos necesarios dentro de la matriz, como claves del índice. Y, los índices de cobertura no necesitan ninguna atención especial. Sin embargo, para crear índices de matrices de cobertura, el también DEBE ser a la lista de otras claves de índice proporcionada a la sentencia CREATE INDEX. Todos los detalles del array son necesarios para que N1QL evalúe correctamente los predicados en la consulta. Por ejemplo, el siguiente comando crea un índice de matriz de cobertura en el directorio 'horario[].vuelo' valores en el couchbase 'muestra-viaje conjunto de datos:
1 2 3 |
CREAR ÍNDICE isched EN `viaje-muestra`(DISTINTO ARRAY i.vuelo PARA i EN horario FIN, horario) DONDE (tipo = "ruta") Y (longitud_array(horario) < 10); |
Tenga en cuenta que el campo de matriz 'Horario como clave de índice adicional. Por el contrario, un índice de matriz no cubierta no requiere eso, y se crea de la siguiente manera:
1 2 3 |
CREAR ÍNDICE isched EN `viaje-muestra`(DISTINTO ARRAY i.vuelo PARA i EN horario FIN) DONDE (tipo = "ruta") Y (longitud_array(horario) < 10); |
La siguiente sentencia SELECT muestra cómo utilizar el índice de matriz de cobertura. Encuentra "los horarios de las rutas aéreas de United Airlines que tienen menos de 10 vuelos programados en una semana".
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
EXPLICAR SELECCIONE horario DESDE `viaje-muestra` UTILICE ÍNDICE(isched_covered) DONDE CUALQUIER i EN horario SATISFACE i.vuelo COMO "UA%" FIN Y longitud_array(horario) < 10 Y tipo = "ruta"; [ { "plan": { "#operator": "Secuencia", "~niños": [ { "#operator": "DistinctScan", "escanear": { "#operator": "IndexScan", "tapas": [ "cover ((distinct (array (`i`.`flight`) for `i` in (`travel-sample`.`schedule`) end)))", "cubrir ((`viaje-muestra`.`programa`))", "cover ((meta(`viaje-muestra`).`id`))" ], "filter_covers": { "cover ((`viaje-muestra`.`tipo`))": "ruta", "cover ((array_length((`viaje-muestra`.`programa`)) < 10))": verdadero }, "índice": "isched_covered", "index_id": "547b2c11add40fa6", "espacio clave": "viaje-muestra", "espacio de nombres": "por defecto", "vanos": [ { "Rango": { "Alto": [ ""UB"" ], "Inclusión": 0, "Bajo": [ ""UA"", "null" ] } } ], "usando": "gsi" } }, { "#operator": "Paralelo", "~niño": { "#operator": "Secuencia", "~niños": [ { "#operator": "Filtro", "condición": "((any `i` in cover ((`viaje-muestra`.`programa`)) satisfies ((`i`.`vuelo`) like "UA%") end and cover ((array_length((`viaje-muestra`.`programa`)) < 10))) and (cover ((`viaje-muestra`.`tipo`)) = "ruta"))" }, { "#operator": "ProyectoInicial", "result_terms": [ { "expr": "cubrir ((`viaje-muestra`.`programa`))" } ] }, { "#operator": "ProyectoFinal" } ] } } ] }, "texto": "SELECT schedule FROM `travel-sample` USE INDEX(isched_covered)nWHERE ANY i IN schedule SATISFIES i.flight LIKE "UA%" ENDn AND array_length(horario) < 10 n AND type = "ruta";" } ] |
Tenga en cuenta que el SELECT sigue las reglas de selección de índices descritas en la siguiente subsección.
- Los predicados de la cláusula where (array_length(horario) < 10) y (tipo = "ruta") coinciden con los de la definición del índice.
- Las claves del índice i.vuelo y horario utilizando la variable exacta 'i' utilizado en la definición del índice
- El plan de consulta explain muestra los atributos y filtros/predicados cubiertos por el índice de array 'isched_covered'
Rendimiento
Los índices de matrices cubiertas obtienen el mejor rendimiento para las consultas que pueden aprovechar el índice. Por ejemplo, la consulta anterior tardó 8ms en mi portátil, cuando se utiliza el índice de matriz cubierta 'isched_covered'. Sin embargo, la misma consulta utilizando el índice 'def_tipotardó 3 segundos. Eso es una locura 375x mejor rendimiento para esta consulta.
Normas de selección de índices
Independientemente de los operadores utilizados, el DML debe seguir los requisitos de selección de índices para hacer uso del índice del array.
- En Cláusula WHERE deben utilizarse en las sentencias SELECT u otras sentencias DML, con claves de índice coincidentes especificadas en la definición de CREATE INDEX.
- Para los índices parciales, los predicados utilizados en la definición de CREATE INDEX deben especificarse en el campo Cláusula WHERE del LMD.
- Nombres de variables en el Cláusula WHERE deben coincidir exactamente con los nombres de variable correspondientes utilizados en la definición de CREATE INDEX.
Cuando múltiples índices coincidentes están disponibles, N1QL puede elegir cualquiera de los índices coincidentes para ejecutar la consulta. Si prefiere que su consulta utilice un índice específico, puede "sugerirlo" utilizando la cláusula USE INDEX en el DML.
Soporte para más operadores N1QL
Couchbase 4.5 añade compatibilidad con los operadores UNNEST y TODOS Y CADA UNO para trabajar con índices de matrices. Estos operadores pueden utilizarse en las consultas con índices de matrices cubiertos y no cubiertos. Tenga en cuenta que:
- CUALQUIER ya se admite el operador in la versión Developer Preview. Véase el ejemplo anterior.
- CADA no está soportado en Couchbase 4.5. Sin embargo, el operador ANY AND EVERY sí está soportado. Para aclarar, el operador EVERY evalúa a true para arrays con cero elementos, mientras que ANY AND EVERY evalúa a true cuando el array tiene al menos un elemento coincidente.
Uso de UNNEST con índices de matrices
La indexación de matrices admite la función UNNEST que puede utilizarse para aplanar el atributo del array sobre el que se crea el índice y utilizarlo como parte de la consulta. La sentencia UNNEST debe utilizar exactamente el mismo nombre de variable (es decir 'i en este ejemplo) tal como se utiliza en la sentencia CREATE INDEX. Por ejemplo, la siguiente consulta encuentra “los detalles de las rutas aéreas de United Airlines que tienen menos de 10 vuelos programados a la semana“.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
EXPLICAR SELECCIONE i DESDE `viaje-muestra` t UTILICE ÍNDICE (isched_covered) UNNEST t.horario AS i DONDE (i.vuelo COMO "UA%") Y (longitud_array(t.horario) < 10) Y (t.tipo = "ruta"); [ { "plan": { "#operator": "Secuencia", "~niños": [ { "#operator": "DistinctScan", "escanear": { "#operator": "IndexScan", "tapas": [ "cover ((distinct (array (`i`.`flight`) for `i` in (`t`.`schedule`) end)))", "cover ((`t`.`schedule`))", "cover ((meta(`t`).`id`))" ], "filter_covers": { "cover ((`t`.`type`))": "ruta", "cover ((array_length((`t`.`schedule`)) < 10))": verdadero }, "índice": "isched_covered", "index_id": "547b2c11add40fa6", "espacio clave": "viaje-muestra", "espacio de nombres": "por defecto", "vanos": [ { "Rango": { "Alto": [ ""UB"" ], "Inclusión": 1, "Bajo": [ ""UA"" ] } } ], "usando": "gsi" } }, { "#operator": "Paralelo", "~niño": { "#operator": "Secuencia", "~niños": [ { "#operator": "Unnest", "como": "i", "expr": "cover ((`t`.`schedule`))" }, { "#operator": "Filtro", "condición": "((((`i`.`flight`) como "UA%") and cover ((array_length((`t`.`schedule`)) < 10))) and (cover ((`t`.`type`)) = "ruta"))" }, { "#operator": "ProyectoInicial", "result_terms": [ { "expr": "`i`" } ] }, { "#operator": "ProyectoFinal" } ] } } ] }, "texto": "SELECT i FROM `travel-sample` t nUSE INDEX (isched_covered) nUNNEST t.schedule AS i nWHERE (i.flight LIKE "UA%") AND (array_length(t.horario) < 10) AND (t.tipo = "ruta");" } ] |
Rendimiento
Cubierta Los índices de matrices obtienen el mejor rendimiento para las consultas que pueden aprovechar el índice. Por ejemplo, la consulta anterior tardó 8ms en mi portátil, cuando se utiliza el índice de matriz 'isched_covered‘. Sin embargo, la misma consulta utilizando el índice 'def_tipo' tomó 28seg. Eso es una locura 3500 veces mejor rendimiento para esta consulta.
Uso de ANY AND EVERY con índices de matrices
La indexación de matrices admite TODOS Y CADA UNO operador. Se puede utilizar para encontrar una coincidencia booleana en un conjunto no nulo de elementos de matriz en el que se crea el índice de matriz. Por ejemplo, la siguiente consulta encuentra "la horario de rutas que tienen al menos 1, pero menos de 10, todos los vuelos de United Airlines en una semana".
1 2 3 4 5 |
SELECCIONE horario DESDE `viaje-muestra` UTILICE ÍNDICE (isched_covered) DONDE CUALQUIER Y CADA i EN horario SATISFACE i.vuelo COMO UA% FIN Y longitud_array(horario) < 10 Y tipo = "ruta"; |
Uso de ALL con índice de matriz
En Couchbase 4.5se pueden crear índices de matrices utilizando CREATE INDEX sólo con la palabra clave DISTINCT ARRAY. La versión 4.5 de Couchbase añade soporte para la palabra clave ALL para crear el índice del array con todos los valores de los elementos del array. Por ejemplo,
1 2 3 |
CREAR ÍNDICE isched_all EN `viaje-muestra`(TODOS ARRAY i.vuelo PARA i EN horario FIN) DONDE (tipo = "ruta") Y (longitud_array(horario) < 10); |
Puede obtener más información sobre la indexación de matrices y ver más ejemplos, como los índices de matrices compuestas y anidadas, en el documento Couchbase 4.5 documentacióny compruebe el demo.
Pruébelo y hágame llegar sus preguntas o comentarios, o simplemente dígame lo fantástico que es ;-)
¡Salud!