Los usuarios de bases de datos de todo tipo esperan una optimización basada en los costes. para sus consultas.
Es una característica estándar de todas las bases de datos relacionales tradicionales (RDBMS), pero todavía no ha habido un optimizador basado en costes (CBO) para las bases de datos de documentos NoSQL. Hasta ahora.
La optimización basada en costes para las consultas de Couchbase se lanzó como Vista previa para desarrolladores en Couchbase 6.5, y ya está listo para su disponibilidad general con Couchbase 7.0.
Echemos un vistazo más de cerca a las nuevas características CBO de Couchbase Server 7.0.
A la antigua usanza: Optimización basada en reglas
Es imposible hablar de la optimización basada en costes sin referirse al enfoque anterior de la optimización de consultas a bases de datos: la optimización basada en reglas (RBO).
Con la optimización basada en reglas, el optimizador de consultas considera el uso de cualquier que proporciona una ruta para recuperar el resultado de la consulta. Sin embargo, cuando al optimizador se le presenta más de una ruta para procesar la consulta -es decir, cuando la consulta podría utilizar varios índices- podría acabar utilizando todos índices.
Con la optimización basada en el coste, el optimizador de consultas calcula el coste de utilizar cada índice y, a continuación, decide el plan de ejecución con el coste más bajo.
¿Qué es la optimización basada en costes?
La optimización basada en los costes permite al optimizador de consultas de la base de datos elegir el mejor plan (de menor coste) para procesar una consulta.
Esto es más importante cuando una consulta tiene más de una ruta de ejecución potencial, es decir, más de un índice cualificado. A cada ruta del plan de consulta se le asigna un coste total para todas las operaciones que debe realizar la consulta. Estos costes dependen en particular de la selectividad de los predicados especificados. Para obtener el valor de selectividad de un predicado, es necesario haber calculado previamente las estadísticas de los campos del predicado.
Tenga en cuenta que el valor del coste es una unidad arbitraria de cálculo estadístico: no equivale al coste de los recursos ni al uso de la CPU.
Optimización basada en costes frente a optimización basada en reglas
La optimización de consultas basada en los costes siempre proporciona una ruta de ejecución mejor cuando al optimizador se le presenta más de una opción. Las estadísticas calculadas garantizan que el optimizador conozca la distribución de los datos y, por tanto, la eficacia de un plan de consulta frente a otro.
Por ejemplo, imagine una colección Couchbase que contiene información sobre los clientes y sus direcciones, con un índice en ix1(código postal) y ix2(ciudad). Estadísticamente, hay más códigos postales que ciudades en EE.UU. Pero eso no significa necesariamente que el uso de la ix1(código postal) tiene un coste menor (y por tanto un mejor rendimiento) que el índice ix2(ciudad) índice. ¿Por qué? Porque aún no sabemos si los clientes del sistema están distribuidos uniformemente por todas las ciudades y códigos postales de Estados Unidos. Lo más probable es que no lo estén.
En este caso, son las estadísticas recopiladas previamente por el optimizador basado en costes las que le ayudan a decidir la ruta de consulta de menor coste en tiempo de ejecución.
Con la optimización basada en reglas, si una consulta tiene predicados tanto de ciudad como de código postal, el optimizador de consultas utiliza ambos índices con la exploración de intersección. Sin embargo, el CBO sólo utiliza un índice, el que tenga el menor coste en función de los datos de la colección.
Cómo activar la optimización basada en costes en Couchbase
Hay dos pasos importantes que debe seguir para utilizar la optimización basada en costes en Couchbase Server 7.0:
1. Activar la función CBO
Actualmente el optimizador basado en costes está activado por defecto en Couchbase 7.0.
Sin embargo, puede desactivarlo con la opción N1QL Valor de Control de Características en Configuración->Configuración de Consultas. Si planea utilizar la optimización basada en costes, asegúrese de que está activada.
2. Recopilar estadísticas
Además de tener activado el optimizador basado en costes en su clúster, también debe haber recopilado estadísticas sobre los campos subyacentes para los índices utilizados por sus consultas. Aquí tienes un ejemplo de consulta sobre cómo hacerlo:
| 1 | ACTUALIZACIÓN ESTADÍSTICAS PARA<espacio clave> (<índice_expr1>,..)  | 
Por ejemplo, utilizando el viaje-muestra la consulta anterior tendría el siguiente aspecto:
| 1 | ACTUALIZACIÓN ESTADÍSTICAS PARA `viaje-muestra`.Por defecto.hotel (ciudad); | 
También puede recopilar las estadísticas según el nombre del índice:
| 1 | ACTUALIZACIÓN ESTADÍSTICAS PARA `viaje-muestra`.Por defecto.ruta.def_route_schedule_utc; | 
Tenga en cuenta que también puede desactivar el optimizador basado en costes utilizando la opción cbo_flag en su API, o borrando las estadísticas con UPDATE ESTADÍSTICAS  DELETE (,..).
El cubo del sistema CBO
Cuando haya activado la optimización basada en costes y haya recopilado estadísticas, observará que hay un Bucket adicional en su cluster llamado N1QL_SYSTEM_BUCKET.N1QL_SYSTEM_SCOPE.N1QL_CBO_STAT. El acceso directo a este cubo está restringido a los administradores del sistema.
Utilización de la ACTUALIZAR ESTADÍSTICAS puede añadir más estadísticas al cubo o eliminar las estadísticas con ACTUALIZAR ESTADÍSTICAS PARA  BORRAR.
Optimizador basado en costes en acción
Veamos con más detalle cómo funciona la optimización basada en costes en Couchbase 7.0 utilizando la función viaje-muestra
Mejor selección de índices con optimización basada en los costes
Supongamos que ha definido dos índices para el archivo viaje-muestra._default.airport
| 1 2 | CREAR ÍNDICE def_aeropuerto_ciudad_país EN aeropuerto(ciudad,país);  CREAR ÍNDICE def_airport_faa EN aeropuerto(faa); | 
Y usted tiene una pregunta a continuación:
| 1 | SELECCIONAR * DESDE aeropuerto DONDE ciudad = "Nueva York" Y faa = "JFK"; | 
Si no se utilizara la optimización basada en costes anterior, el plan de ejecución del optimizador basado en reglas para la consulta anterior sería:

Obsérvese que, dado que los predicados de consulta están tanto en el ciudad y faa ambos índices se utilizan en la búsqueda de intersección. Obtenga más información sobre las exploraciones de intersección en este artículo: Ingredientes de rendimiento para NoSQL: Exploraciones de intersección en N1QL.
A continuación, active la optimización basada en costes para la consulta de la base de datos. Como la CBO ya está activada por defecto, lo único que hay que hacer es recopilar las estadísticas.
| 1 | ACTUALIZACIÓN ESTADÍSTICAS PARA aeropuerto(ciudad, faa); | 
Una vez recopiladas las estadísticas, ejecute el programa SELECCIONE pregunta de nuevo.
Verá que el plan de ejecución pasa a utilizar únicamente el comando aeropuerto.faa índice. Este cambio se debe a que las estadísticas están indicando al optimizador que el faa tiene una mejor selectividad en comparación con el ciudad campo. Por lo tanto, el aeropuerto.faa es el índice más eficaz para la consulta.

Una mejor JOIN con optimización basada en los costes
Veamos otro ejemplo de optimización de consulta basada en costes que ilustra cómo el optimizador basado en costes elige un mejor tipo de JOIN entre aeropuerto y ruta.
En primer lugar, creamos un índice para rastrear el aeropuerto de origen:
| 1 | CREAR ÍNDICE `def_route_sourceairport` EN `viaje-muestra`.`Por defecto`.`ruta`(`fuenteaeropuerto`) | 
Y a continuación utilizamos la siguiente consulta:
| 1 | SELECCIONE DISTINTO ruta.destinoaeropuerto DESDE aeropuerto ÚNASE A ruta EN aeropuerto.faa = ruta.fuenteaeropuerto; | 
Con el antiguo optimizador basado en reglas, el plan de ejecución de la consulta anterior tendría el siguiente aspecto:

Observe que el plan de ejecución RBO anterior utiliza un bucle anidado para UNIR la colección de aeropuertos a la colección de rutas.
A continuación, debe activar la optimización basada en costes para la consulta. Como la CBO ya está activada por defecto, todo lo que tiene que hacer es recopilar las estadísticas del campo en la Colección.
| 1 2 | ACTUALIZACIÓN ESTADÍSTICAS PARA ruta(fuenteaeropuerto); ACTUALIZACIÓN ESTADÍSTICAS PARA aeropuerto(faa); | 
Con las estadísticas de optimización basadas en costes disponibles en los dos campos subyacentes para los índices, el optimizador pasa a utilizar un HASH para la colección JOIN.

Solución de problemas del optimizador basado en costes en Couchbase
- La optimización basada en costes está activada por defecto en Couchbase 7.0. Sin embargo, las estadísticas deben estar presentes en los campos específicos de su Bucket/Collections antes de que el optimizador basado en costes funcione eficazmente.
- Puede desactivar la optimización basada en costes a nivel de clúster utilizando el campo Control de funciones N1QL añadiendo 16 al valor. Se trata de un conjunto con x10 bits.
- El servicio de consulta no actualiza automáticamente las estadísticas CBO. Las estadísticas deben recopilarse periódicamente o después de un cambio significativo en el contenido de la colección. Recomiendo recopilar las estadísticas después de una gran carga de datos; de lo contrario, una ejecución semanal debería ser suficiente.
- La optimización basada en los costes sólo se tiene en cuenta para una consulta si las estadísticas están disponibles para todos los índices considerados por el optimizador. Puede recopilar las estadísticas de todos los índices de un espacio de claves determinado de la siguiente forma:
 12ACTUALIZACIÓN ESTADÍSTICAS PARA <colección> ÍNDICE((SELECCIONE RAW nombre de sistema:índicesDONDE estado=en línea Y id_espacio_clave='<collection_name>' Y bucket_id='<bucket_name>' Y ámbito_id='))
Más recursos
Para obtener más información sobre el optimizador basado en costes para JSON, y sobre la versión 7.0 de Couchbase en general, consulta los siguientes recursos:
Gran artículo, gracias. Pequeña errata en el último párrafo de la sección "A better JOIN with CBO". La palabra NO debería ser AHORA. Como en
..., el optimizador pasará a utilizar un HASH para la colección JOIN.