Servidor Couchbase 7.0 (Enterprise Edition) introdujo un Optimizador Basado en Costes (CBO). Las versiones anteriores de Couchbase Server usaban un Optimizador Basado en Reglas (RBO). Couchbase Server ha evolucionado naturalmente de RBO a CBO como la mayoría de los principales sistemas de bases de datos relacionales.
El CBO utiliza estimaciones de costes para elegir un plan de consulta calculado a partir de las estadísticas del optimizador. Las estadísticas del optimizador se recopilan utilizando las sentencias UPDATE STATISTICS o ANALYZE en una consulta SQL++ (a la que nos referiremos más adelante como N1QL).
Sentencia UPDATE STATISTICS/ANALYZE
El nuevo ACTUALIZAR ESTADÍSTICAS o ANALIZAR activan la recopilación de estadísticas del optimizador necesarias para la funcionalidad CBO. Actualmente, un usuario emite estas nuevas sentencias manualmente, lo que calcula las estadísticas del optimizador sobre el espacio de claves/colección, los índices definidos en el espacio de claves/colección y la información de distribución (en forma de histogramas) sobre una lista de términos (expresiones).
Cuando hay varios nodos de consulta, las estadísticas del optimizador recopiladas de un nodo de consulta están disponibles en todos los nodos de consulta.
El nuevo N1QL_SYSTEM_BUCKET
El nuevo optimizador recopila estadísticas a través del ACTUALIZA ESTADÍSTICAS/ANALIZA y los almacena en un nuevo cubo (N1QL_SYSTEM_BUCKET), concretamente en un nuevo ámbito (N1QL_ÁMBITO_SISTEMA) y una nueva colección (N1QL_CBO_STATS).
La primera vez que se ejecuta, el ACTUALIZAR ESTADÍSTICAS/ANALIZAR crea automáticamente este nuevo bucket/ámbito/colección. También se crea automáticamente un índice primario.
Descarga del nuevo cubo/ámbito/colección
Estos nuevos objetos del sistema (cubo, ámbito, colección) pueden eliminarse de la base de datos, con lo que todas las estadísticas del optimizador dejarán de estar disponibles.
Cualquier consulta futura no aprovechará la funcionalidad CBO hasta que un usuario vuelva a solicitar que se analicen las estadísticas. Hasta ese momento, el sistema vuelve a RBO para la planificación de la consulta.
Cuota de memoria para el nuevo bucket/ámbito/colección
El nuevo cubo del sistema (N1QL_SYSTEM_BUCKET) se crea con una cuota de memoria mínima de 100 MB. En un sistema de gran tamaño, los administradores de bases de datos deben supervisar la residencia de memoria en el bucket y aumentar la cuota de memoria cuando sea necesario para evitar que su residencia de memoria caiga por debajo del nivel recomendado de 15%.
Sintaxis
A alto nivel, hay tres aspectos de una sentencia UPDATE STATISTICS/ANALYZE:
1. Estadísticas del espacio clave/colección - recogidos cada vez que se emite una declaración de actualización/análisis
2. Estadísticas del índice - reunidos para los índices "pertinentes
3. Estadísticas de distribución (histograma) - recogidos en los términos especificados.
Hay varias formas de especificar la lista de términos para los que se recogen estadísticas de distribución.
Proporcionar una lista de términos para elaborar estadísticas
1 2 3 |
ACTUALIZACIÓN ESTADÍSTICAS [PARA] espacio clave(término1, término2, ...) ANALIZAR [KEYSPACE/COLECCIÓN] espacio clave(término1, término2, ...) |
Estas dos afirmaciones son equivalentes. En ACTUALIZAR ESTADÍSTICAS tiene una palabra clave FOR opcional seguida de un nombre de espacio de claves. En ANALIZAR tiene un parámetro opcional KEYSPACE o COLECCIÓN seguida de un nombre de espacio de claves.
El nombre del espacio clave suele ser un nombre de colección. Puede especificar un nombre de cubo como nombre del espacio de claves, en cuyo caso las estadísticas del optimizador se recopilan en el espacio de claves Por defecto recaudación en virtud de la Por defecto alcance para ese cubo.
La lista de términos es similar a la lista de expresiones utilizadas en el CREAR ÍNDICE declaración. De hecho, cualquier expresión admitida en una sentencia CREAR ÍNDICE también se puede utilizar como término en una declaración ACTUALIZAR ESTADÍSTICAS/ANALIZAR declaración. Por ejemplo:
1 2 3 |
ACTUALIZACIÓN ESTADÍSTICAS PARA `viaje-muestra`.inventario.aeropuerto(ciudad, país) ANALIZAR `viaje-muestra`.inventario.aeropuerto(ciudad, país) |
Las afirmaciones anteriores pueden simplificarse si contexto de consulta se establece en muestra-viaje.inventario:
1 2 |
ACTUALIZACIÓN ESTADÍSTICAS PARA aeropuerto(ciudad, país) ANALIZAR aeropuerto(ciudad, país) |
Expresión clave funcional
De forma similar a la especificación de una clave de índice funcional en un archivo CREAR ÍNDICE también puede especificar una tecla de función en una sentencia ACTUALIZAR ESTADÍSTICAS/ANALIZAR declaración. Por ejemplo:
1 2 3 |
ACTUALIZACIÓN ESTADÍSTICAS PARA aeropuerto(inferior(país)) ANALIZAR aeropuerto(inferior(país)) |
Expresión de clave de matriz
Como especificar una clave de índice de matriz en un CREAR ÍNDICE también puede especificar una clave de índice de matriz en una sentencia ACTUALIZAR ESTADÍSTICAS/ANALIZAR declaración. Por ejemplo:
1 2 3 |
ACTUALIZACIÓN ESTADÍSTICAS PARA ruta(DISTINTO ARRAY v.vuelo PARA v EN horario FIN) ANALIZAR COLECCIÓN ruta(DISTINTO ARRAY v.vuelo PARA v EN horario FIN) |
o utilizando la versión abreviada:
1 2 3 |
ACTUALIZACIÓN ESTADÍSTICAS PARA hotel(TODOS me gusta_público) ANALIZAR KEYSPACE hotel(TODOS me gusta_público) |
Análisis de uno o varios índices
Las sentencias Analyze pueden especificar opcionalmente uno o más índices utilizando la función ÍNDICE opción:
1 2 3 |
ACTUALIZACIÓN ESTADÍSTICAS PARA aeropuerto ÍNDICE(def_inventario_ciudad_aeropuerto, def_inventory_airport_faa) ANALIZAR aeropuerto ÍNDICE(def_inventario_ciudad_aeropuerto, def_inventory_airport_faa) |
Cuando el ÍNDICE la lista de expresiones de clave de índice para todos los índices se utiliza como lista de términos para la opción ACTUALIZAR ESTADÍSTICAS/ANALIZAR declaración.
Expresiones en el DONDE para un índice parcial también se añaden a los términos para analizar. Así, la cláusula ÍNDICE es un atajo práctico, ya que el usuario no necesita enumerar todos los términos explícitamente.
Las afirmaciones anteriores son equivalentes a las siguientes, ya que cada índice sólo tiene una clave de índice, y no hay ninguna DONDE para cualquiera de los índices referenciados:
1 2 3 |
ACTUALIZACIÓN ESTADÍSTICAS PARA aeropuerto(ciudad, faa) ANALIZAR aeropuerto(ciudad, faa) |
Analizar todos los índices
Para ir un paso más allá, puede utilizar la opción INDEX ALL para una sentencia UPDATE STATISTICS/ANALYZE, que considera todos los índices disponibles definidos en la colección y que están en estado online. Por ejemplo
1 2 3 |
ACTUALIZACIÓN ESTADÍSTICAS PARA aeropuerto ÍNDICE TODOS ANALIZAR aeropuerto ÍNDICE TODOS |
Mientras que otras opciones permiten especificar un nombre de cubo o de colección, la opción ÍNDICE TODOS sólo es válida para una colección. Especificación de ÍNDICE TODOS con un nombre de cubo devolverá un error.
Índice de residencia
El análisis también actualiza las estadísticas del optimizador para los índices relevantes. Cuando se especifica una lista de términos, la lista de índices aplicable se construye comprobando las claves de índice que hacen referencia a cualquiera de los términos de la lista. Las listas de índices relevantes se deducen a partir de los índices cuando la función ÍNDICE o ÍNDICE ALSe utiliza la opción L.
Las estadísticas del optimizador para un índice sólo pueden recopilarse cuando el índice es, al menos parcialmente, residente en memoria. Las estadísticas del optimizador se obtienen de la parte de un índice residente en memoria. Una mayor proporción de memoria residente produce estadísticas del optimizador más precisas para ese índice.
Si un índice tiene un índice residente en memoria igual a cero, la sentencia de optimización devuelve las siguientes advertencias:
1 2 3 4 5 6 |
"advertencias": [ { "código": 5390, "msg": "El índice def_inventory_airport_city no está en la memoria" } ], |
Cláusula opcional WITH
Similar a la CREAR ÍNDICE también puede especificar un CON para añadir opciones de análisis estadístico. Por ejemplo:
1 2 3 |
ACTUALIZACIÓN ESTADÍSTICAS PARA aeropuerto(ciudad, país) CON {"resolución": 0.5} ANALIZAR aeropuerto(ciudad, país) CON {"resolución": 0.5} |
Actualmente se admiten las siguientes opciones en CON cláusula de un ACTUALIZAR ESTADÍSTICAS/ANALIZAR declaración: resolución, tamaño_muestra, tamaño_lote, tiempo_espera_estadística_actualización. Cada uno de ellos se trata a continuación.
La opción de resolución
La distribución estadística del término (histograma) se representa como una serie de "bins". La resolución indica qué porcentaje de documentos está representado en cada "bin". Por defecto, se utiliza una resolución de 1,0 (es decir, 100 bins).
Puede especificar una resolución diferente en la cláusula WITH. Por ejemplo, si necesita una granularidad más fina de las estadísticas de distribución, puede especificar una resolución menor (correspondiente a un mayor número de bins).
Tenga en cuenta que cuanto menor sea la resolución (mayor número de intervalos), más muestras se necesitarán para construir el histograma y más tiempo/recursos se necesitarán para completar el histograma. ACTUALIZAR ESTADÍSTICAS/ANALIZAR declaración.
El intervalo válido de la opción de resolución es 0,02 - 5,0.
La opción sample_size
Las muestras son necesarias para construir las estadísticas de distribución (histograma) de los términos especificados en un ACTUALIZAR ESTADÍSTICAS/ANALIZAR declaración. La resolución determina el tamaño de la muestra y no está directamente relacionada con el número de documentos de una colección.
Puede especificar el tamaño de muestra que se utilizará. Sin embargo, se requiere un tamaño de muestra mínimo para una resolución dada. Si el tamaño de la muestra es menor que el tamaño mínimo de muestra requerido, se utilizará en su lugar el tamaño mínimo de muestra requerido y se devolverá una advertencia.
La opción batch_size
La construcción de histogramas requiere una operación de clasificación y, por tanto, consume muchos recursos. Para evitar una utilización excesiva de recursos, los histogramas se construyen por lotes. Por defecto, cada lote procesa hasta 10 términos para la construcción del histograma. Si se enumeran más, o la combinación de las expresiones clave del índice (de los índices especificados por las opciones INDEX) supera los diez términos, se necesitan varios lotes para procesar todos los términos.
Puede especificar un tamaño_lote para que el servidor sepa cuántos términos procesar en cada lote. Por ejemplo, un usuario puede solicitar un tamaño de lote mayor si el sistema no está sobrecargado y hay muchos recursos informáticos disponibles. Por otro lado, si el sistema ya está sobrecargado, se puede utilizar un tamaño de lote menor. Se trata de un equilibrio entre el uso de recursos y la duración del análisis.
La opción update_statistics_timeout
En ACTUALIZAR ESTADÍSTICAS/ANALIZAR es una tarea de mantenimiento y puede hacer que el tiempo de respuesta sea significativamente superior al de una consulta simple, especialmente cuando se requieren varios lotes.
Por defecto, a las sentencias de actualización/análisis se les aplica un tiempo de espera de 60 segundos. Se puede especificar un valor opcional (en segundos) para el tiempo de espera. Tenga en cuenta que el valor de tiempo de espera se aplica a cada lote cuando se requieren varios lotes.
Cláusula DELETE
Los usuarios pueden soltar las estadísticas actuales del optimizador utilizando un BORRAR con la sentencia update/analyze. Esta cláusula desactiva selectivamente CBO para una consulta o conjunto de consultas.
Hay un par de maneras de especificar el BORRAR especificando una lista de términos para los que se eliminarán las estadísticas del optimizador o solicitando la eliminación de todas las estadísticas del optimizador para un espacio de claves/colección.
Cláusula DELETE con una lista de términos
1 2 3 |
ACTUALIZACIÓN ESTADÍSTICAS PARA aeropuerto BORRAR (ciudad, país) ANALIZAR COLECCIÓN aeropuerto BORRAR ESTADÍSTICAS(ciudad, país) |
La consulta borrará las estadísticas de distribución sólo para los términos especificados con esta opción. No se verán afectadas otras estadísticas del optimizador, como las del espacio de claves y las del índice. Con esta opción, si una consulta tiene un predicado en el campo "ciudad" o "país" de la colección "aeropuerto", CBO se desactivará para la consulta.
Cláusula DELETE para todas las estadísticas del optimizador de un espacio de claves/colección
1 2 3 |
ACTUALIZACIÓN ESTADÍSTICAS PARA aeropuerto BORRAR TODOS ANALIZAR KEYSPACE aeropuerto BORRAR ESTADÍSTICAS |
Con esta opción, se eliminarán todas las estadísticas del optimizador para la colección "airport", incluidas las estadísticas de espacios clave, estadísticas de índices y estadísticas de distribución. Cualquier consulta que haga referencia a la colección "airport" tendrá desactivado CBO en este caso.
¿Qué campos/expresiones analizar?
¿Cómo puedo saber qué campos/expresiones incluir en un archivo ACTUALIZAR ESTADÍSTICAS/ANALIZAR ¿expresión? Por regla general, cualquier expresión a la que se haga referencia en una consulta (excepto las que sólo aparecen en la cláusula de proyección) requiere estadísticas del optimizador.
Cláusulas WHERE, ON, GROUP BY, ORDER BY
Expresiones referenciadas en el DONDE, EN, AGRUPAR POR y ORDENAR POR requieren estadísticas del optimizador. Por ejemplo:
1 2 3 4 |
SELECCIONE a.nombre del aeropuerto, r.aerolínea DESDE aeropuerto a ÚNASE A ruta r EN a.faa = r.fuenteaeropuerto DONDE a.ciudad = "San Francisco" PEDIR POR a.nombre del aeropuerto; |
Para esta consulta, se requieren estadísticas del optimizador en:
1 2 |
aeropuerto(faa, ciudad, nombre del aeropuerto) ruta(fuenteaeropuerto) |
Si se utiliza una expresión más compleja:
1 2 3 |
SELECCIONAR * DESDE aeropuerto DONDE inferior(país) = "nos"; |
Para esta consulta, se requieren estadísticas del optimizador en:
1 |
aeropuerto(inferior(país)) |
Expresiones de índice de matriz
Para CUALQUIER o TODOS Y CADA UNO que utilizan índices de matriz, se requieren estadísticas del optimizador para la expresión clave de índice de matriz correspondiente. Por ejemplo:
1 2 3 |
SELECCIONAR * DESDE ruta DONDE CUALQUIER v EN horario SATISFACE v.vuelo = "FL121" FIN; |
Para esta consulta, se requieren estadísticas del optimizador en:
1 |
ruta(DISTINTO ARRAY v.vuelo PARA v EN horario FIN) |
Tenga en cuenta que la expresión utilizada es la misma que la expresión de clave de índice de matriz para la definición de índice de matriz correspondiente.
Para un UNNEST operación:
1 2 3 |
SELECCIONE r.destinoaeropuerto DESDE ruta r UNNEST r.horario AS s DONDE s.vuelo = "FL121"; |
Para esta consulta, se requieren estadísticas del optimizador en:
1 |
ruta(TODOS ARRAY v.vuelo PARA v EN horario FIN) |
De nuevo, la expresión utilizada es la misma que la expresión de clave de índice de matriz para la definición de índice de matriz correspondiente.
Subconsultas y expresiones comunes de tabla (CTE)
Para una consulta que incluya una subconsulta o una CTE, consulte el bloque de consulta de la subconsulta o la CTE para determinar qué expresiones requieren estadísticas del optimizador:
1 2 3 4 |
CON usairport AS (SELECCIONE nombre del aeropuerto, faa DESDE aeropuerto DONDE inferior(país) = "nos") SELECCIONAR * DESDE usairport; |
Si se observa el bloque de consulta que define la CTE, las estadísticas del optimizador son necesarias en:
1 |
aeropuerto(inferior(país)) |
Funciones de ventana
Si se utiliza una función ventana, se requieren estadísticas del optimizador en las expresiones utilizadas en las cláusulas PARTITION BY y ORDER BY:
1 2 |
SELECCIONE CONTAR(1) EN (PARTICIÓN POR país) DESDE aerolínea; |
Para esta consulta, se requieren estadísticas del optimizador en:
1 |
aerolínea(país) |
Ver estadísticas del optimizador
Se han introducido dos nuevos espacios de claves del sistema para las estadísticas del optimizador: system:dictionary y system:dictionary_cache. El primero corresponde a los documentos en disco almacenados en N1QL_SYSTEM_BUCKET.N1QL_SYSTEM_SCOPE.N1QL_CBO_STATS, mientras que system:dictionary_cache corresponde a la representación en memoria caché de un subconjunto de la misma información.
La caché del diccionario se inicializa cuando se inicia un nodo de consulta, y la información de la caché se rellena al ejecutar las consultas. Los datos recuperados de sistema:diccionario será el mismo independientemente del nodo de consulta que obtenga la información cuando se utilicen varios nodos de consulta.
Sin embargo, la información almacenada en caché de todos los nodos de consulta de un clúster multinodo estará en sistema:dictionary_cache, donde cada nodo puede tener potencialmente un subconjunto diferente de información almacenada en caché.
Esta consulta muestra la estadística en system:dictionary:
1 2 3 |
SELECCIONAR * DESDE sistema:diccionario DONDE `cubo` = "viaje-muestra" Y `alcance` = "inventario" Y `espacio clave` = "aeropuerto"; |
Los resultados de la consulta son:
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 |
{ "diccionario": { "avgDocKeySize": 12, "avgDocSize": 278, "cubo": "viaje-muestra", "distributionKeys": [ "país", "lower(país)" ], "docCount": 1968, "índices": [ { "indexId": "4978a27d62bc592a", "nombredelíndice": "def_inventory_airport_primary", "indexStats": [ { "avgItemSize": 23, "avgPageSize": 7202, "numItems": 1968, "numPages": 6, "resRatio": 1 } ] }, { "indexId": "c5071b3ac2730bff", "nombredelíndice": "def_inventory_airport_faa", "indexStats": [ { "avgItemSize": 32, "avgPageSize": 9394, "numItems": 1968, "numPages": 7, "resRatio": 1 } ] }, { "indexId": "e260327a9933350e", "nombredelíndice": "def_inventario_ciudad_aeropuerto", "indexStats": [ { "avgItemSize": 39, "avgPageSize": 11410, "numItems": 1968, "numPages": 7, "resRatio": 1 } ] } ], "espacio clave": "aeropuerto", "espacio de nombres": "por defecto", "ámbito": "inventario" } } |
Cada entrada contiene información básica sobre el espacio de claves, una matriz de distribuciónClaves para los que se dispone de histogramas y una matriz de información de índices.
Del mismo modo, al consultar system:dictionary_cache:
1 2 3 |
SELECCIONAR * DESDE sistema:dictionary_cache DONDE `cubo` = "viaje-muestra" Y `alcance` = "inventario" Y `espacio clave` = "aeropuerto"; |
El resultado es el mismo que el sistema:diccionario excepto por un campo de nodo adicional que muestra las entradas de diferentes nodos de consulta.
Explicar el resultado con optimizer_estimates
Cuando las estadísticas apropiadas del optimizador están disponibles, la salida EXPLAIN contendrá una nueva sección optimizer_estimates para cada operador. Estas secciones reflejan la estimación del optimizador para la información de costes para este operador y todos sus hijos. Por ejemplo
1 |
EXPLICAR SELECCIONAR * DESDE aeropuerto DONDE ciudad = "San Francisco"; |
La siguiente salida corresponde al operador IndexScan3:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
{ "#operator": "IndexScan3", "índice": "aeropuerto_ciudad_país", ...... "optimizador_estimaciones": { "cardinalidad": 1.1764705882352944, "coste": 12.212415941159103, "fr_cost": 12.180553549985238, "tamaño": 12 }, "vanos": [ ...... ], ...... }, |
Tener la optimizador_estimaciones para un operador es una indicación de que la base de datos está utilizando CBO para esta etapa del proceso de planificación de la consulta.
Resumen
Couchbase 7.0 incorpora nuevas e innovadoras características a la base de datos; la adición del Optimizador Basado en Costes (CBO) es sólo una de muchas. Las consultas de actualización/análisis que se muestran en esta entrada del blog son esenciales para recopilar las estadísticas que necesita el CBO para funcionar de forma eficiente.
Una vez que la base de datos recopila estadísticas precisas del optimizador, la salida de EXPLAIN muestra las estimaciones que CBO utilizará para elegir un plan de consulta. Esto ayudará a guiarle hacia una generación de consultas más eficiente y predecible en el futuro.
- Más información sobre la CBO en el Documentos de Couchbase
- Más información Lanzamiento de Couchbase 7 y sus novedades
- Sumérgete en SQL para JSON: Lenguaje de consulta SQL
Esto ha sido útil, gracias Bingjie.
Una consulta: En la actualidad, no existe ninguna tarea automática, como las disponibles en Oracle, para recopilar estadísticas. Así que hay que hacerlo manualmente de forma regular, quizás con cron jobs. ¿Es esto correcto?
Sí, su interpretación es correcta. Actualmente, la recopilación de estadísticas del optimizador es un proceso manual. Estamos estudiando mejoras en este ámbito para facilitar su uso.