{"id":4935,"date":"2018-04-03T19:31:02","date_gmt":"2018-04-04T02:31:02","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=4935"},"modified":"2025-06-13T23:43:08","modified_gmt":"2025-06-14T06:43:08","slug":"understanding-index-grouping-aggregation-couchbase-n1ql-query","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/es\/understanding-index-grouping-aggregation-couchbase-n1ql-query\/","title":{"rendered":"Entendiendo la Agrupaci\u00f3n y Agregaci\u00f3n de \u00cdndices en Couchbase N1QL Query"},"content":{"rendered":"<p><a href=\"https:\/\/www.couchbase.com\/blog\/es\/\"><span style=\"font-weight: 400\">Couchbase<\/span><\/a> <a href=\"https:\/\/docs.couchbase.com\/server\/5.5\/n1ql\/n1ql-language-reference\/index.html\"><span style=\"font-weight: 400\">N1QL<\/span><\/a><span style=\"font-weight: 400\"> es un moderno motor de procesamiento de consultas dise\u00f1ado para proporcionar SQL agregado para JSON por \u00edndice sobre datos distribuidos con un modelo de datos flexible. Las bases de datos modernas se despliegan en clusters masivos. El uso de JSON proporciona un modo de datos flexible. N1QL soporta SQL agregado por \u00edndice para JSON para facilitar el procesamiento de consultas.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Las aplicaciones y los controladores de bases de datos env\u00edan la consulta N1QL a uno de los nodos de consulta disponibles en un cl\u00faster. El nodo de consulta analiza la consulta y utiliza los metadatos de los objetos subyacentes para determinar el plan de ejecuci\u00f3n \u00f3ptimo, que luego ejecuta. Durante la ejecuci\u00f3n, en funci\u00f3n de la consulta, utilizando los \u00edndices aplicables, el nodo de consulta trabaja con los nodos de \u00edndices y datos para recuperar los datos y realizar las operaciones previstas. Dado que Couchbase es una base de datos modular en cl\u00faster, puedes escalar los servicios de datos, \u00edndices y consultas para adaptarlos a tus objetivos de rendimiento y disponibilidad.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Antes de Couchbase 5.5, incluso cuando una consulta con GROUP BY y\/o agregados estaba cubierta por un \u00edndice, la consulta obten\u00eda todos los datos relevantes del indexador y realizaba la agrupaci\u00f3n\/agregaci\u00f3n de los datos dentro del motor de consultas.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-4941 aligncenter\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2018\/04\/Screen-Shot-2018-04-03-at-3.46.48-PM-300x169.png\" alt=\"\" width=\"772\" height=\"435\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-3.46.48-PM-300x169.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-3.46.48-PM-1024x578.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-3.46.48-PM-768x433.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-3.46.48-PM-1536x867.png 1536w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-3.46.48-PM-20x11.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-3.46.48-PM-1320x745.png 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-3.46.48-PM.png 1666w\" sizes=\"auto, (max-width: 772px) 100vw, 772px\" \/><\/p>\n<p><span style=\"font-weight: 400\">En Couchbase 5.5 se ha mejorado el planificador de consultas para que solicite de forma inteligente al indexador que realice agrupaciones y agregaciones adem\u00e1s del escaneo de rangos. <\/span><b>para el \u00edndice de cobertura<\/b><span style=\"font-weight: 400\">. El indexador se ha mejorado para realizar agrupaciones, COUNT(), SUM(), MIN(), MAX(), AVG() y operaciones relacionadas sobre la marcha. \u00a0<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-4940 aligncenter\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2018\/04\/Screen-Shot-2018-04-03-at-3.46.59-PM-300x164.png\" alt=\"\" width=\"782\" height=\"427\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-3.46.59-PM-300x164.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-3.46.59-PM-1024x559.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-3.46.59-PM-768x419.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-3.46.59-PM-1536x838.png 1536w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-3.46.59-PM-20x11.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-3.46.59-PM-1320x720.png 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-3.46.59-PM.png 1682w\" sizes=\"auto, (max-width: 782px) 100vw, 782px\" \/><\/p>\n<p><span style=\"font-weight: 400\">Esto no requiere cambios en la consulta del usuario, pero s\u00ed un buen dise\u00f1o del \u00edndice para cubrir la consulta y ordenar las claves del \u00edndice.  No todas las consultas se beneficiar\u00e1n de esta optimizaci\u00f3n, y no todos los \u00edndices pueden acelerar todas las operaciones de agrupaci\u00f3n y agregaci\u00f3n. Comprender los patrones adecuados te ayudar\u00e1 a dise\u00f1ar tus \u00edndices y consultas. La agrupaci\u00f3n y agregaci\u00f3n de \u00edndices en el \u00edndice secundario global es compatible con ambos motores de almacenamiento: GSI est\u00e1ndar y GSI optimizado para memoria (MOI). La agrupaci\u00f3n y agregaci\u00f3n de \u00edndices s\u00f3lo se admite en Enterprise Edition.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Este paso de reducci\u00f3n de realizar el GROUP BY y la Agregaci\u00f3n por el indexador reduce la cantidad de transferencia de datos y E\/S de disco, resultando en:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Mejora del tiempo de respuesta a las consultas<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Mejor utilizaci\u00f3n de los recursos<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Baja latencia<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Gran escalabilidad<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Bajo coste total de propiedad<\/span><\/li>\n<\/ul>\n<h2><b>Rendimiento<\/b><\/h2>\n<p><span style=\"font-weight: 400\">La agrupaci\u00f3n y agregaci\u00f3n de \u00edndices puede mejorar el rendimiento de las consultas en \u00f3rdenes de magnitud y reducir dr\u00e1sticamente las latencias. La siguiente tabla muestra algunos ejemplos de mediciones de latencia de consulta.<\/span><\/p>\n<p><span style=\"font-weight: 400\">\u00cdndice :<\/span><\/p>\n<pre class=\"theme:github lang:mysql decode:true\">CREAR \u00cdNDICE idx_ts_tipo_pa\u00eds_ciudad EN `viaje-muestra` (tipo, pa\u00eds, ciudad);<\/pre>\n<p>&nbsp;<\/p>\n<div class=\"responsive-table\">\n<table style=\"height: 1284px\" width=\"1025\">\n<tbody>\n<tr>\n<td><span style=\"font-weight: 400\">Consulta<\/span><\/td>\n<td><span style=\"font-weight: 400\">Descripci\u00f3n<\/span><\/td>\n<td><span style=\"font-weight: 400\">5.0 Latencias <\/span><\/td>\n<td><span style=\"font-weight: 400\">5.5 Latencias<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\">SELECT t.type, COUNT(type) AS cnt\u00a0<\/span><span style=\"font-weight: 400\">FROM `travel-sample` AS t <\/span><span style=\"font-weight: 400\">WHERE t.type IS NOT NULL <\/span><span style=\"font-weight: 400\">GROUP BY t.type;<\/span><\/td>\n<td>\n<ul>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">GROUP BY clave de \u00edndice principal <\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Agregaci\u00f3n <\/span><\/li>\n<\/ul>\n<\/td>\n<td><span style=\"font-weight: 400\">230 ms<\/span><\/td>\n<td><span style=\"font-weight: 400\">13ms<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\">SELECT t.type, COUNT(1) AS cnt, <\/span><span style=\"font-weight: 400\">COUNT(DISTINCT ciudad) AS cntdciudad <\/span><span style=\"font-weight: 400\">FROM `travel-sample` AS t <\/span><span style=\"font-weight: 400\">WHERE t.type IN [\"hotel\", \"aeropuerto\"]. <\/span><span style=\"font-weight: 400\">GROUP BY t.type, t.country;<\/span><\/td>\n<td>\n<ul>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">GROUP BY m\u00faltiples claves de \u00edndice principales<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Agregados m\u00faltiples<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Agregado Distinto<\/span><\/li>\n<\/ul>\n<\/td>\n<td><span style=\"font-weight: 400\">40ms<\/span><\/td>\n<td><span style=\"font-weight: 400\">7ms<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\">SELECT t.pa\u00eds, COUNT(ciudad) AS cnt <\/span><span style=\"font-weight: 400\">FROM `travel-sample` AS t\u00a0<\/span><span style=\"font-weight: 400\">DONDE <\/span><b>t.type = \"aeropuerto\" <\/b><span style=\"font-weight: 400\">GROUP BY t.country;<\/span><\/td>\n<td>\n<ul>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">GROUP BY primera clave de \u00edndice principal sin igualdad<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Agregaci\u00f3n<\/span><\/li>\n<\/ul>\n<\/td>\n<td><span style=\"font-weight: 400\">25ms<\/span><\/td>\n<td><span style=\"font-weight: 400\">3ms<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\">SELECT t.ciudad, cnt <\/span><span style=\"font-weight: 400\">FROM `travel-sample` AS t <\/span><span style=\"font-weight: 400\">WHERE t.type IS NOT NULL <\/span><span style=\"font-weight: 400\">GROUP BY t.ciudad <\/span><span style=\"font-weight: 400\">LETTING cnt = COUNT(ciudad) <\/span><span style=\"font-weight: 400\">HAVING cnt &gt; 0 ;<\/span><\/td>\n<td>\n<ul>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">GROUP BY clave de \u00edndice no principal<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">cl\u00e1usula de arrendamiento<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Cl\u00e1usula HAVING<\/span><\/li>\n<\/ul>\n<\/td>\n<td><span style=\"font-weight: 400\">300 ms<\/span><\/td>\n<td><span style=\"font-weight: 400\">160 ms<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<h2><b>Visi\u00f3n general de la agrupaci\u00f3n y agregaci\u00f3n de \u00edndices<\/b><\/h2>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-4938 aligncenter\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2018\/04\/Screen-Shot-2018-04-03-at-10.08.36-AM-300x161.png\" alt=\"\" width=\"861\" height=\"462\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-10.08.36-AM-300x161.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-10.08.36-AM-1024x549.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-10.08.36-AM-768x412.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-10.08.36-AM-20x11.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-10.08.36-AM-1320x708.png 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-10.08.36-AM.png 1388w\" sizes=\"auto, (max-width: 861px) 100vw, 861px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400\">La figura anterior muestra todas las posibles fases por las que pasa una consulta SELECT para devolver los resultados. <\/span><span style=\"font-weight: 400\">\u00a0<\/span><span style=\"font-weight: 400\">El proceso de filtrado toma el espacio de claves inicial y produce un subconjunto \u00f3ptimo de los documentos que interesan a la consulta. Para producir el subconjunto m\u00e1s peque\u00f1o posible, se utilizan \u00edndices para aplicar tantos predicados como sea posible. El predicado de la consulta indica el subconjunto de datos que interesa. Durante la fase de planificaci\u00f3n de la consulta, seleccionamos los \u00edndices que se van a utilizar. A continuaci\u00f3n, para cada \u00edndice, decidimos los predicados que debe aplicar cada \u00edndice. Los predicados de consulta se traducen en escaneos de rango en el plan de consulta y se pasan al indexador. <\/span><\/p>\n<p><span style=\"font-weight: 400\">Si la consulta no tiene JOINs y est\u00e1 cubierta por un \u00edndice, se pueden eliminar las fases Fetch y Join.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-4937 aligncenter\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2018\/04\/Screen-Shot-2018-04-03-at-11.29.20-AM-300x162.png\" alt=\"\" width=\"839\" height=\"453\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-11.29.20-AM-300x162.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-11.29.20-AM-1024x552.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-11.29.20-AM-768x414.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-11.29.20-AM-20x11.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-11.29.20-AM-1320x711.png 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-11.29.20-AM.png 1366w\" sizes=\"auto, (max-width: 839px) 100vw, 839px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400\">Cuando todos los predicados se traducen exactamente a escaneos de rango, la fase de filtrado tambi\u00e9n puede eliminarse. En esa situaci\u00f3n, el escaneo y la agregaci\u00f3n est\u00e1n uno al lado del otro, y como el indexador tiene la capacidad de hacer agregaci\u00f3n, esa fase se puede hacer en el nodo indexador. En algunos casos, las fases de ordenaci\u00f3n, desplazamiento y l\u00edmite tambi\u00e9n pueden realizarse en el nodo del indexador.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-4936 aligncenter\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2018\/04\/Screen-Shot-2018-04-03-at-11.29.31-AM-300x163.png\" alt=\"\" width=\"837\" height=\"455\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-11.29.31-AM-300x163.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-11.29.31-AM-1024x556.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-11.29.31-AM-768x417.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-11.29.31-AM-20x11.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-11.29.31-AM-1320x716.png 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-11.29.31-AM.png 1356w\" sizes=\"auto, (max-width: 837px) 100vw, 837px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400\">El siguiente diagrama de flujo describe c\u00f3mo el planificador de consultas decide realizar la agregaci\u00f3n de \u00edndices para cada bloque de consulta de la consulta. Si la agregaci\u00f3n de \u00edndices no es posible, las agregaciones se realizan en el motor de consultas.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-4943 aligncenter\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2018\/04\/Screen-Shot-2018-04-03-at-4.01.01-PM-300x234.png\" alt=\"\" width=\"944\" height=\"736\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-4.01.01-PM-300x234.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-4.01.01-PM-768x600.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-4.01.01-PM-20x16.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-4.01.01-PM-1320x1031.png 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-4.01.01-PM.png 1388w\" sizes=\"auto, (max-width: 944px) 100vw, 944px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400\">For example, let&#8217;s compare the previous vs. current performance of using GROUP BY and examine the EXPLAIN plan of the following query that uses an index defined on the Couchbase `travel-sample` bucket:<\/span><\/p>\n<pre class=\"theme:github lang:mysql decode:true\">CREATE INDEX `def_type` ON `travel-sample`(`type`);\r\n<\/pre>\n<p><span style=\"font-weight: 400\">Considere la consulta: <\/span><\/p>\n<pre class=\"theme:github lang:mysql decode:true\">SELECT tipo, COUNT(tipo)\r\nFROM `viaje-muestra\r\nWHERE type IS NOT MISSING\r\nGROUP BY tipo;<\/pre>\n<p><span style=\"font-weight: 400\">Antes de la versi\u00f3n 5.5 de Couchbase, este motor de consultas obten\u00eda los datos relevantes del indexador y agrupaba y agregaba los datos dentro del motor de consultas. Esta sencilla consulta tarda unos 250 ms.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-4939 alignnone\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2018\/04\/Screen-Shot-2018-04-02-at-7.39.06-PM-300x47.png\" alt=\"\" width=\"848\" height=\"133\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-02-at-7.39.06-PM-300x47.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-02-at-7.39.06-PM-1024x160.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-02-at-7.39.06-PM-768x120.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-02-at-7.39.06-PM-1536x240.png 1536w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-02-at-7.39.06-PM-20x3.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-02-at-7.39.06-PM-1320x206.png 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-02-at-7.39.06-PM.png 1690w\" sizes=\"auto, (max-width: 848px) 100vw, 848px\" \/><\/p>\n<p><span style=\"font-weight: 400\">Ahora, en la versi\u00f3n 5.5 de Couchbase, esta consulta utiliza el mismo \u00edndice def_type, pero se ejecuta en menos de 20 ms. En la explicaci\u00f3n de abajo, puedes ver menos pasos y la falta del paso de agrupaci\u00f3n despu\u00e9s del escaneo del \u00edndice porque el paso de escaneo del \u00edndice tambi\u00e9n hace la agrupaci\u00f3n y agregaci\u00f3n.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-4949 aligncenter\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2018\/04\/Screen-Shot-2018-04-03-at-7.04.11-PM-300x36.png\" alt=\"\" width=\"850\" height=\"102\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-7.04.11-PM-300x36.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-7.04.11-PM-1024x124.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-7.04.11-PM-768x93.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-7.04.11-PM-20x2.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-7.04.11-PM-1320x159.png 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-7.04.11-PM.png 1524w\" sizes=\"auto, (max-width: 850px) 100vw, 850px\" \/><\/p>\n<p><span style=\"font-weight: 400\">A medida que aumente la complejidad de los datos y las consultas, tambi\u00e9n lo har\u00e1 el rendimiento (tanto latencia como rendimiento). \u00a0\u00a0<\/span><\/p>\n<h2><b>Comprensi\u00f3n de EXPLAIN de la agrupaci\u00f3n y agregaci\u00f3n de \u00edndices<\/b><\/h2>\n<p><span style=\"font-weight: 400\">Mirando la explicaci\u00f3n de la consulta:<\/span><\/p>\n<pre class=\"theme:github lang:mysql decode:true\">EXPLAIN SELECT type, COUNT(type) FROM `viajes-muestra` WHERE type IS NOT MISSING GROUP BY type;{<\/pre>\n<pre class=\"theme:github lang:mysql decode:true\">{\r\n  \"plan\": {\r\n    \"#operator\": \"Sequence\",\r\n    \"~children\": [\r\n      {\r\n        \"#operator\": \"IndexScan3\",\r\n        \"covers\": [\r\n          \"cover ((`viaje-muestra`.`tipo`))\",\r\n          \"cover ((meta(`muestra-de-viaje`).`id`))\",\r\n          \"cover (count(cover ((`viaje-muestra`.`type`))))\"\r\n        ],\r\n        \"index\": \"def_type\",\r\n        \"index_group_aggs\": {\r\n          \"agregados\": [\r\n            {\r\n              \"agregado\": \"COUNT\",\r\n              \"depende\": [\r\n                0\r\n              ],\r\n              \"expr\": \"cover ((`viaje-muestra`.`tipo`))\",\r\n              \"id\": 2,\r\n              \"keypos\": 0\r\n            }\r\n          ],\r\n          \"depends\": [\r\n            0\r\n          ],\r\n          \"group\": [\r\n            {\r\n              \"depende\": [\r\n                0\r\n              ],\r\n              \"expr\": \"cover ((`viaje-muestra`.`tipo`))\",\r\n              \"id\": 0,\r\n              \"keypos\": 0\r\n            }\r\n          ]\r\n        },\r\n        \"index_id\": \"b948c92b44c2739f\",\r\n        \"index_projection\": {\r\n          \"entry_keys\": [\r\n            0,\r\n            2\r\n          ]\r\n        },\r\n        \"keyspace\": \"muestra-viaje\",\r\n        \"namespace\": \"default\",\r\n        \"spans\": [\r\n          {\r\n            \"exact\": true\r\n            \"range\": [\r\n              {\r\n                \"inclusi\u00f3n\": 1,\r\n                \"bajo\": \"null\"\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\": \"Secuencia\",\r\n          \"~children\": [\r\n            {\r\n              \"#operator\": \"InitialProject\",\r\n              \"result_terms\": [\r\n                {\r\n                  \"expr\": \"cover ((`viaje-muestra`.`tipo`))\"\r\n                },\r\n                {\r\n                  \"expr\": \"cover (count(cover ((`viaje-muestra`.`tipo`))))\"\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  \"text\": \"SELECT type, COUNT(type) FROM `viaje-muestra` WHERE type IS NOT MISSING GROUP BY type;\"\r\n}<\/pre>\n<p>Ver\u00e1 \"index_group_aggs\" en la secci\u00f3n IndexScan (es decir, \"#operator\": \"IndexScan3\"). Si \"index_group_aggs\" est\u00e1 ausente, el servicio de consulta est\u00e1 realizando la agrupaci\u00f3n y agregaci\u00f3n. Si la consulta est\u00e1 presente est\u00e1 utilizando la agrupaci\u00f3n y agregaci\u00f3n de \u00edndices y tiene toda la informaci\u00f3n relevante que el indexador requiere para la agrupaci\u00f3n y agregaci\u00f3n. La siguiente tabla describe c\u00f3mo interpretar la diversa informaci\u00f3n del objeto index_group_aggs.<\/p>\n<div class=\"responsive-table\">\n<table>\n<tbody>\n<tr>\n<td><b>Nombre del campo<\/b><\/td>\n<td><b>Descripci\u00f3n<\/b><\/td>\n<td><b>N\u00fameros de l\u00ednea del ejemplo<\/b><\/td>\n<td><b>Explicar el texto en el ejemplo<\/b><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\">agregados<\/span><\/td>\n<td><span style=\"font-weight: 400\">Matriz de objetos Aggregate, y cada objeto representa un agregado. La ausencia de este elemento significa que en la consulta s\u00f3lo est\u00e1 presente group by.<\/span><\/td>\n<td><span style=\"font-weight: 400\">14-24<\/span><\/td>\n<td><span style=\"font-weight: 400\">agregados<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\"> \u00a0\u00a0agregado<\/span><\/td>\n<td><span style=\"font-weight: 400\">Operaci\u00f3n agregada (<\/span><span style=\"font-weight: 400\">MAX\/MIN\/SUM\/COUNT\/COUNTN)<\/span><span style=\"font-weight: 400\">.<\/span><\/td>\n<td><span style=\"font-weight: 400\">16<\/span><\/td>\n<td><span style=\"font-weight: 400\">CONTAR<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\">distinto<\/span><\/td>\n<td><span style=\"font-weight: 400\">El modificador agregado es DISTINTO<\/span><\/td>\n<td><span style=\"font-weight: 400\">&#8211;<\/span><\/td>\n<td><span style=\"font-weight: 400\">Falso(Cuando es verdadero s\u00f3lo aparece)<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\"> \u00a0\u00a0depende<\/span><\/td>\n<td><span style=\"font-weight: 400\">Lista de posiciones clave de \u00edndice (empezando por 0) de las que depende la expresi\u00f3n agregada.<\/span><\/td>\n<td><span style=\"font-weight: 400\">17-19<\/span><\/td>\n<td><span style=\"font-weight: 400\">0 <\/span><span style=\"font-weight: 400\">(porque el tipo es la clave 0 del \u00edndice def_type)<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\"> \u00a0\u00a0expr<\/span><\/td>\n<td><span style=\"font-weight: 400\">expresi\u00f3n agregada<\/span><\/td>\n<td><span style=\"font-weight: 400\">20<\/span><\/td>\n<td><span style=\"font-weight: 400\">cover ((`travel-sample`.`type`))<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\"> \u00a0\u00a0id<\/span><\/td>\n<td><span style=\"font-weight: 400\">ID \u00fanico dado internamente y que se utilizar\u00e1 en <\/span><span style=\"font-weight: 400\">proyecci\u00f3n_\u00edndice<\/span><\/td>\n<td><span style=\"font-weight: 400\">21<\/span><\/td>\n<td><span style=\"font-weight: 400\">2<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\"> \u00a0\u00a0keypos<\/span><\/td>\n<td><span style=\"font-weight: 400\">Indicador que indica el uso de la expresi\u00f3n en la posici\u00f3n clave del \u00edndice o del campo expr.<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Un valor &gt; -1 significa que la expresi\u00f3n agregada coincide exactamente con la posici\u00f3n de la clave de \u00edndice correspondiente (empezando por 0).<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Un valor de -1 significa que la expresi\u00f3n agregada ] no coincide exactamente con la posici\u00f3n clave del \u00edndice y utiliza la expresi\u00f3n del campo expr.<\/span><\/li>\n<\/ul>\n<\/td>\n<td><span style=\"font-weight: 400\">22<\/span><\/td>\n<td><span style=\"font-weight: 400\">0 <\/span><span style=\"font-weight: 400\">(porque el tipo es la clave 0 del \u00edndice def_type)<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\">depende<\/span><\/td>\n<td><span style=\"font-weight: 400\">Lista de posiciones clave de \u00edndice de las que dependen las expresiones de grupos\/agregados (lista consolidada)<\/span><\/td>\n<td><span style=\"font-weight: 400\">25-27<\/span><\/td>\n<td><span style=\"font-weight: 400\">0<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\">grupo<\/span><\/td>\n<td><span style=\"font-weight: 400\">Matriz de objetos GROUP BY, y cada objeto representa una clave de grupo. La ausencia de este elemento significa que no hay ninguna cl\u00e1usula GROUP BY presente en la consulta.<\/span><\/td>\n<td><span style=\"font-weight: 400\">28-37<\/span><\/td>\n<td><span style=\"font-weight: 400\">grupo<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\"> \u00a0\u00a0depende<\/span><\/td>\n<td><span style=\"font-weight: 400\">Lista de posiciones de las teclas de \u00edndice (empezando por 0) de las que depende la expresi\u00f3n de grupo.<\/span><\/td>\n<td><span style=\"font-weight: 400\">30-32<\/span><\/td>\n<td><span style=\"font-weight: 400\">0<\/span><\/p>\n<p><span style=\"font-weight: 400\">(porque el tipo es la clave 0 del \u00edndice clave del \u00edndice def_type)<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\"> \u00a0\u00a0expr<\/span><\/td>\n<td><span style=\"font-weight: 400\">expresi\u00f3n de grupo.<\/span><\/td>\n<td><span style=\"font-weight: 400\">33<\/span><\/td>\n<td><span style=\"font-weight: 400\">cover ((`travel-sample`.`type`))<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\"> \u00a0\u00a0id<\/span><\/td>\n<td><span style=\"font-weight: 400\">ID \u00fanico dado internamente y que se utilizar\u00e1 en <\/span><span style=\"font-weight: 400\">proyecci\u00f3n_\u00edndice.<\/span><\/td>\n<td><span style=\"font-weight: 400\">34<\/span><\/td>\n<td><span style=\"font-weight: 400\">0<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\"> \u00a0\u00a0keypos<\/span><\/td>\n<td><span style=\"font-weight: 400\">Indicador que indica el uso de la expresi\u00f3n en la posici\u00f3n clave del \u00edndice o del campo expr.<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Un valor &gt; -1 significa que la expresi\u00f3n del grupo coincide exactamente con la posici\u00f3n de la clave de \u00edndice correspondiente (empezando por 0).<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Un valor de -1 significa que la clave de grupo no coincide exactamente con la posici\u00f3n de la clave de \u00edndice y utiliza la expresi\u00f3n del campo expr.<\/span><\/li>\n<\/ul>\n<\/td>\n<td><span style=\"font-weight: 400\">35<\/span><\/td>\n<td><span style=\"font-weight: 400\">0 <\/span><span style=\"font-weight: 400\">(porque el tipo es la clave 0 del \u00edndice def_type)<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p><span style=\"font-weight: 400\">El campo \"covers\" es un array que contiene todas las claves de \u00edndice, claves de documento (META().id), expresiones de claves de grupo que no coinciden exactamente con las claves de \u00edndice (ordenadas por id), agregados ordenados por id. Tambi\u00e9n \"Index_projection\" tendr\u00e1 todos los ids de grupo\/agregado.<\/span><\/p>\n<pre class=\"theme:github lang:mysql decode:true\">\"cubiertas\": [\r\n         \"portada ((`viaje-muestra`.`tipo`))\", \u2190 clave de \u00edndice (0)\r\n         \"cover ((meta(`viaje-muestra`).`id`))\", \u2190 clave de documento (1)\r\n         \"cover (count(cover ((`viaje-muestra`.`type`))))\"     \u2190 agregado (2)\r\n       ]<\/pre>\n<p><span style=\"font-weight: 400\">In above case group expression `type` is same Index key of index `def_type`. It is not included twice.<\/span><\/p>\n<h2><b>Detalles <\/b><b>Agrupaci\u00f3n y agregaci\u00f3n de \u00edndices<\/b><\/h2>\n<p><span style=\"font-weight: 400\">Utilizaremos ejemplos para mostrar c\u00f3mo funciona la agrupaci\u00f3n y agregaci\u00f3n de \u00edndices. Para seguir los ejemplos <\/span><span style=\"font-weight: 400\">cree un bucket \"default\" e inserte los siguientes documentos:<\/span><\/p>\n<pre class=\"theme:github lang:mysql decode:true\">INSERT INTO default (CLAVE,VALOR)\r\n    VALUES (\"ga0001\", {\"c0\":1, \"c1\":10, \"c2\":100, \"c3\":1000, \"c4\":10000, \"a1\":[{\"id\":1}, {\"id\":1}, {\"id\":2}, {\"id\":3}, {\"id\":4}, {\"id\":5}]}),\r\n    VALORES (\"ga0002\", {\"c0\":1, \"c1\":20, \"c2\":200, \"c3\":2000, \"c4\":20000, \"a1\":[{\"id\":1}, {\"id\":1}, {\"id\":2}, {\"id\":3}, {\"id\":4}, {\"id\":5}]}),\r\n    VALORES (\"ga0003\", {\"c0\":1, \"c1\":10, \"c2\":300, \"c3\":3000, \"c4\":30000, \"a1\":[{\"id\":1}, {\"id\":1}, {\"id\":2}, {\"id\":3}, {\"id\":4}, {\"id\":5}]}),\r\n    VALORES (\"ga0004\", {\"c0\":1, \"c1\":20, \"c2\":400, \"c3\":4000, \"c4\":40000, \"a1\":[{\"id\":1}, {\"id\":1}, {\"id\":2}, {\"id\":3}, {\"id\":4}, {\"id\":5}]}),\r\n    VALORES (\"ga0005\", {\"c0\":2, \"c1\":10, \"c2\":100, \"c3\":5000, \"c4\":50000, \"a1\":[{\"id\":1}, {\"id\":1}, {\"id\":2}, {\"id\":3}, {\"id\":4}, {\"id\":5}]}),\r\n    VALORES (\"ga0006\", {\"c0\":2, \"c1\":20, \"c2\":200, \"c3\":6000, \"c4\":60000, \"a1\":[{\"id\":1}, {\"id\":1}, {\"id\":2}, {\"id\":3}, {\"id\":4}, {\"id\":5}]}),\r\n    VALORES (\"ga0007\", {\"c0\":2, \"c1\":10, \"c2\":300, \"c3\":7000, \"c4\":70000, \"a1\":[{\"id\":1}, {\"id\":1}, {\"id\":2}, {\"id\":3}, {\"id\":4}, {\"id\":5}]}),\r\n    VALUES (\"ga0008\", {\"c0\":2, \"c1\":20, \"c2\":400, \"c3\":8000, \"c4\":80000, \"a1\":[{\"id\":1}, {\"id\":1}, {\"id\":2}, {\"id\":3}, {\"id\":4}, {\"id\":5}]});<\/pre>\n<h4><\/h4>\n<h3><span style=\"font-weight: 400\">Ejemplo 1: Agrupaci\u00f3n por claves de \u00edndice principales<\/span><\/h3>\n<p><span style=\"font-weight: 400\">Consideremos la consulta y el \u00edndice siguientes:<\/span><\/p>\n<pre class=\"theme:github lang:mysql decode:true\">SELECT d.c0 AS c0, d.c1 AS c1, SUM(d.c3) AS sumc3,\r\n       AVG(d.c4) AS avgc4, COUNT(DISTINCT d.c2) AS dcountc2\r\nFROM por defecto COMO d\r\nWHERE d.c0 &gt; 0\r\nGROUP BY d.c0, d.c1\r\nORDER BY d.c0, d.c1\r\nOFFSET 1\r\nLIMIT 2;<\/pre>\n<p>\u00cdndice requerido:<\/p>\n<pre class=\"theme:github lang:mysql decode:true\">CREAR \u00cdNDICE idx1 EN default(c0, c1, c2, c3, c4);<\/pre>\n<p><span style=\"font-weight: 400\">\u00a0 \u00a0 \u00a0La consulta tiene GROUP BY y m\u00faltiples agregados, algunos de los agregados tienen el modificador DISTINCT. La consulta se puede cubrir con el \u00edndice idx1 y el predicado (d.c0 &gt; 0) se puede convertir en un escaneo de rango exacto y pasarlo al escaneo de \u00edndice. Por lo tanto, la combinaci\u00f3n de \u00edndice y consulta cumple los requisitos de agrupaci\u00f3n y agregaci\u00f3n de \u00edndices.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Los \u00edndices se ordenan y agrupan de forma natural por el orden de definici\u00f3n de la clave del \u00edndice. En la consulta anterior, las claves GROUP BY (d.c0, d.c1) coinciden exactamente con las claves principales (c0, c1) del \u00edndice. Por lo tanto, el \u00edndice tiene los datos de cada grupo juntos, el indexador producir\u00e1 una fila por grupo, es decir, agregaci\u00f3n completa.  Adem\u00e1s, la consulta tiene un agregado que tiene el modificador DISTINCT y coincide exactamente con una de las claves del \u00edndice con una posici\u00f3n menor o igual al n\u00famero de claves de grupo m\u00e1s una (es decir, hay 2 claves de grupo, el modificador DISTINCT puede ser cualquiera de las claves de \u00edndice en la posici\u00f3n 0,1,2 porque la clave de \u00edndice seguida de las claves de grupo y el modificador DISTINCT pueden aplicarse sin ordenaci\u00f3n). Por lo tanto, la consulta anterior es adecuada para que el indexador gestione la agrupaci\u00f3n y la agregaci\u00f3n. <\/span><\/p>\n<p><span style=\"font-weight: 400\">Si el grupo carece de una de las claves de \u00edndice principales y existe un predicado de igualdad, se realiza una optimizaci\u00f3n especial tratando la clave de \u00edndice impl\u00edcitamente presente en las claves de grupo y determinando si la agregaci\u00f3n completa es posible o no. Para el \u00edndice de partici\u00f3n, todas las claves de partici\u00f3n deben estar presentes en las claves de grupo para generar agregaciones completas.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-4948 aligncenter\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2018\/04\/Screen-Shot-2018-04-03-at-7.04.34-PM-300x79.png\" alt=\"\" width=\"870\" height=\"229\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-7.04.34-PM-300x79.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-7.04.34-PM-1024x268.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-7.04.34-PM-768x201.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-7.04.34-PM-20x5.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-7.04.34-PM-1320x346.png 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-7.04.34-PM.png 1512w\" sizes=\"auto, (max-width: 870px) 100vw, 870px\" \/><\/p>\n<p><span style=\"font-weight: 400\">El \u00e1rbol de ejecuci\u00f3n gr\u00e1fico anterior muestra el escaneo de \u00edndices (IndexScan3) realizando agregaciones de escaneo y agrupaci\u00f3n de \u00edndices. Se proyectan los resultados del escaneo de \u00edndices.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Veamos la explicaci\u00f3n basada en el texto :<\/span><\/p>\n<pre class=\"theme:github lang:mysql decode:true\">{\r\n  \"plan\": {\r\n    \"#operator\": \"Sequence\",\r\n    \"~children\": [\r\n      {\r\n        \"#operator\": \"Sequence\",\r\n        \"~children\": [\r\n          {\r\n            \"#operator\": \"IndexScan3\",\r\n            \"as\": \"d\",\r\n            \"covers\": [\r\n              \"portada ((`d`.`c0`))\",\r\n              \"cover ((`d`.`c1`))\",\r\n              \"cover ((`d`.`c2`))\",\r\n              \"cover ((`d`.`c3`))\",\r\n              \"cover ((`d`.`c4`))\",\r\n              \"cobertura ((meta(`d`).`id`))\",\r\n              \"cover (count(distinct cover ((`d`.`c2`))))\",\r\n              \"cover (countn(cover ((`d`.`c4`))))\",\r\n              \"cover (sum(cover ((`d`.`c3`))))\",\r\n              \"cover (sum(cover ((`d`.`c4`))))\"\r\n            ],\r\n            \"index\": \"idx1\",\r\n            \"index_group_aggs\": {\r\n              \"agregados\": [\r\n                {\r\n                  \"agregado\": \"COUNT\",\r\n                  \"depende\": [\r\n                    2\r\n                  ],\r\n                  \"distinct\": true\r\n                  \"expr\": \"cover ((`d`.`c2`))\",\r\n                  \"id\": 6,\r\n                  \"keypos\": 2\r\n                },\r\n                {\r\n                  \"aggregate\": \"COUNTN\",\r\n                  \"depends\": [\r\n                    4\r\n                  ],\r\n                  \"expr\": \"cover ((`d`.`c4`))\",\r\n                  \"id\": 7,\r\n                  \"keypos\": 4\r\n                },\r\n                {\r\n                  \"aggregate\": \"SUM\",\r\n                  \"depende\": [\r\n                    3\r\n                  ],\r\n                  \"expr\": \"cover ((`d`.`c3`))\",\r\n                  \"id\": 8,\r\n                  \"keypos\": 3\r\n                },\r\n                {\r\n                  \"aggregate\": \"SUM\",\r\n                  \"depende\": [\r\n                    4\r\n                  ],\r\n                  \"expr\": \"cover ((`d`.`c4`))\",\r\n                  \"id\": 9,\r\n                  \"keypos\": 4\r\n                }\r\n              ],\r\n              \"depends\": [\r\n                0,\r\n                1,\r\n                2,\r\n                3,\r\n                4\r\n              ],\r\n              \"grupo\": [\r\n                {\r\n                  \"depende\": [\r\n                    0\r\n                  ],\r\n                  \"expr\": \"cover ((`d`.`c0`))\",\r\n                  \"id\": 0,\r\n                  \"keypos\": 0\r\n                },\r\n                {\r\n                  \"depends\": [\r\n                    1\r\n                  ],\r\n                  \"expr\": \"cover ((`d`.`c1`))\",\r\n                  \"id\": 1,\r\n                  \"keypos\": 1\r\n                }\r\n              ]\r\n            },\r\n            \"index_id\": \"d06df7c5d379cd5\",\r\n            \"index_order\": [\r\n              {\r\n                \"keypos\": 0\r\n              },\r\n              {\r\n                \"keypos\": 1\r\n              }\r\n            ],\r\n            \"index_projection\": {\r\n              \"entry_keys\": [\r\n                0,\r\n                1,\r\n                6,\r\n                7,\r\n                8,\r\n                9\r\n              ]\r\n            },\r\n            \"keyspace\": \"default\",\r\n            \"limit\": \"2\",\r\n            \"namespace\": \"default\",\r\n            \"offset\": \"1\",\r\n            \"spans\": [\r\n              {\r\n                \"exact\": true\r\n                \"range\": [\r\n                  {\r\n                    \"inclusi\u00f3n\": 0,\r\n                    \"bajo\": \"0\"\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\": \"InitialProject\",\r\n                  \"result_terms\": [\r\n                    {\r\n                      \"as\": \"c0\",\r\n                      \"expr\": \"cover ((`d`.`c0`))\"\r\n                    },\r\n                    {\r\n                      \"as\": \"c1\",\r\n                      \"expr\": \"cover ((`d`.`c1`))\"\r\n                    },\r\n                    {\r\n                      \"as\": \"sumc3\",\r\n                      \"expr\": \"cover (sum(cover ((`d`.`c3`))))\"\r\n                    },\r\n                    {\r\n                      \"as\": \"avgc4\",\r\n                      \"expr\": \"cover (sum(cover ((`d`.`c4`)))) \/ cover (countn(cover ((`d`.`c4`)))))\"\r\n                    },\r\n                    {\r\n                      \"as\": \"dcountc2\",\r\n                      \"expr\": \"cover (count(distinct cover ((`d`.`c2`))))\"\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        \"#operator\": \"Limit\",\r\n        \"expr\": \"2\"\r\n      }\r\n    ]\r\n  },\r\n  \"text\": \"SELECT d.c0 AS c0, d.c1 AS c1, SUM(d.c3) AS sumc3, AVG(d.c4) AS avgc4, COUNT(DISTINCT d.c2) AS dcountc2 FROM default AS d\\nWHERE d.c0 &gt; 0 GROUP BY d.c0, d.c1 ORDER BY d.c0, d.c1 OFFSET 1 LIMIT 2;\"\r\n}<\/pre>\n<ul>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">El \"index_group_aggs\" (l\u00edneas 24-89) en la secci\u00f3n IndexScan (es decir, \"#operator\": \"IndexScan3\") muestra la consulta utilizando la agrupaci\u00f3n y agregaci\u00f3n de \u00edndices. <\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Si la consulta utiliza agrupaci\u00f3n y agregaci\u00f3n de \u00edndices, los predicados se convierten exactamente en escaneos de rangos y se pasan al escaneo de \u00edndices como parte de los rangos, por lo que no habr\u00e1 ning\u00fan operador Filter en la explicaci\u00f3n.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\"> Como las claves de agrupaci\u00f3n coinciden exactamente con las claves de \u00edndice principales, el indexador producir\u00e1 agregaciones completas. Por lo tanto, tambi\u00e9n eliminamos la agrupaci\u00f3n en el servicio de consulta (no hay operadores InitialGroup, IntermediateGroup, FinalGroup en la explicaci\u00f3n). <\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">El indexador proyecta \"index_projection\" (l\u00edneas 99-107) incluyendo todas las claves de grupo y agregados.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">La consulta ORDER BY coincide con las claves de \u00edndice principales y GROUP BY est\u00e1 en las claves de \u00edndice principales, por lo que podemos utilizar el orden de \u00edndice. Esto se puede encontrar en explicar (l\u00edneas 91-98) y no utilizar\u00e1 \"#operator\": \"Order\" entre las l\u00edneas 164-165. \u00a0<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Como la consulta puede utilizar el orden del \u00edndice y no hay cl\u00e1usula HAVING en la consulta, los valores \"offset\" y \"limit\" pueden pasarse al indexador. <\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Esto se puede encontrar en la l\u00ednea 112, 110. El \"offset\" se puede aplicar s\u00f3lo una vez no ver\u00e1 \"#operator\": \"Offset\" entre las l\u00edneas 164-165, Pero volver a aplicar el \"l\u00edmite\" es no-op. Esto se puede ver en la l\u00ednea 165-168.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">La consulta que contiene AVG(x) se ha reescrito como SUM(x)\/COUNTN(x). COUNTN(x) s\u00f3lo cuenta cuando x es un valor num\u00e9rico.<\/span><\/li>\n<\/ul>\n<h3><span style=\"font-weight: 400\">Ejemplo 2: Agrupaci\u00f3n por claves de \u00edndice principales, LETTING, HAVING <\/span><\/h3>\n<p><span style=\"font-weight: 400\">Consideremos la consulta y el \u00edndice siguientes:<\/span><\/p>\n<pre class=\"theme:github lang:mysql decode:true\">SELECT d.c0 AS c0, d.c1 AS c1, sumc3 AS sumc3,\r\n       AVG(d.c4) AS avgc4, COUNT(DISTINCT d.c2) AS dcountc2\r\nFROM por defecto COMO d\r\nWHERE d.c0 &gt; 0\r\nGROUP BY d.c0, d.c1\r\nLETTING sumc3 = SUM(d.c3)\r\nHAVING sumc3 &gt; 0\r\nORDER BY d.c0, d.c1\r\nOFFSET 1\r\nLIMIT 2;<\/pre>\n<p><span style=\"font-weight: 400\">\u00cdndice requerido:<\/span><\/p>\n<pre class=\"theme:github lang:mysql decode:true\">CREAR \u00cdNDICE idx1 EN default(c0, c1, c2, c3, c4);<\/pre>\n<p><span style=\"font-weight: 400\">La consulta anterior es similar a la del ejemplo 1, pero contiene las cl\u00e1usulas LETTING y HAVING. El indexador no podr\u00e1 manejarlas, por lo que las cl\u00e1usulas LETTING y HAVING se aplican en el servicio de consulta despu\u00e9s de la agrupaci\u00f3n y las agregaciones. Por lo tanto, ver\u00e1 los operadores Let y Filter despu\u00e9s de IndexScan3 en el \u00e1rbol de ejecuci\u00f3n. La cl\u00e1usula Having es un filtro y elimina m\u00e1s elementos, por lo que \"offset\" y \"limit\" no pueden enviarse al indizador y deben aplicarse en el servicio de consulta, pero a\u00fan podemos utilizar el orden del \u00edndice.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-4947 aligncenter\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2018\/04\/Screen-Shot-2018-04-03-at-7.05.02-PM-300x54.png\" alt=\"\" width=\"1239\" height=\"223\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-7.05.02-PM-300x54.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-7.05.02-PM-768x139.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-7.05.02-PM-20x4.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-7.05.02-PM-1320x239.png 1320w\" sizes=\"auto, (max-width: 1239px) 100vw, 1239px\" \/><\/p>\n<h3><span style=\"font-weight: 400\">Ejemplo 3: Agrupaci\u00f3n por claves de \u00edndice no principales<\/span><\/h3>\n<p><span style=\"font-weight: 400\">Consideremos la consulta y el \u00edndice siguientes:<\/span><\/p>\n<pre class=\"theme:github lang:mysql decode:true\">SELECT d.c1 AS c1, d.c2 AS c2, SUM(d.c3) AS sumc3,\r\n       AVG(d.c4) COMO avgc4, COUNT(d.c2) COMO countc2\r\nFROM por defecto COMO d\r\nWHERE d.c0 &gt; 0\r\nGROUP BY d.c1, d.c2\r\nORDER BY d.c1, d.c2\r\nOFFSET 1\r\nLIMIT 2;<\/pre>\n<p><span style=\"font-weight: 400\">\u00cdndice requerido:<\/span><\/p>\n<pre class=\"theme:github lang:mysql decode:true\">CREAR \u00cdNDICE idx1 EN default(c0, c1, c2, c3, c4);\r\n\r\n<\/pre>\n<p><span style=\"font-weight: 400\"> \u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400\">La consulta tiene GROUP BY y m\u00faltiples agregados. La consulta se puede cubrir con el \u00edndice idx1 y el predicado (d.c0 &gt; 0) se puede convertir en escaneo de rango exacto y pasarlo a escaneo de \u00edndice. Por lo tanto, la combinaci\u00f3n de \u00edndice y consulta cumple los requisitos de agrupaci\u00f3n y agregaci\u00f3n de \u00edndices.<\/span><\/p>\n<p><span style=\"font-weight: 400\">En la consulta anterior, las claves GROUP BY (d.c1, d.c2) NO coinciden con las claves principales (c0, c1) del \u00edndice. Los grupos est\u00e1n dispersos por el \u00edndice. Por lo tanto, el indizador producir\u00e1 varias filas por cada grupo, es decir, agregaci\u00f3n parcial. En caso de agregaci\u00f3n parcial, el servicio de consulta realiza la fusi\u00f3n de grupos, la consulta no puede utilizar el orden del \u00edndice ni enviar \"offset\", \"limit\" al indizador.  En caso de agregaci\u00f3n parcial, si alg\u00fan agregado tiene el modificador DISTINCT, la agrupaci\u00f3n de \u00edndices y la agregaci\u00f3n no son posibles. La consulta anterior es adecuada para que el indizador gestione la agrupaci\u00f3n y la agregaci\u00f3n. <\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-4946 aligncenter\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2018\/04\/Screen-Shot-2018-04-03-at-7.05.16-PM-300x60.png\" alt=\"\" width=\"885\" height=\"177\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-7.05.16-PM-300x60.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-7.05.16-PM-768x153.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-7.05.16-PM-20x4.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-7.05.16-PM-1320x262.png 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-7.05.16-PM.png 1520w\" sizes=\"auto, (max-width: 885px) 100vw, 885px\" \/><\/p>\n<p><span style=\"font-weight: 400\">El \u00e1rbol de ejecuci\u00f3n gr\u00e1fico anterior muestra el escaneo de \u00edndices (IndexScan3) realizando agregaciones de escaneo y agrupaci\u00f3n de \u00edndices. Los resultados de la exploraci\u00f3n de \u00edndices se agrupan de nuevo y se proyectan.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Veamos la explicaci\u00f3n basada en el texto :<\/span><\/p>\n<pre class=\"theme:github lang:mysql decode:true\">{\r\n  \"plan\": {\r\n    \"#operator\": \"Sequence\",\r\n    \"~children\": [\r\n      {\r\n        \"#operator\": \"Sequence\",\r\n        \"~children\": [\r\n          {\r\n            \"#operator\": \"IndexScan3\",\r\n            \"as\": \"d\",\r\n            \"covers\": [\r\n              \"portada ((`d`.`c0`))\",\r\n              \"cover ((`d`.`c1`))\",\r\n              \"cover ((`d`.`c2`))\",\r\n              \"cover ((`d`.`c3`))\",\r\n              \"cover ((`d`.`c4`))\",\r\n              \"cover ((meta(`d`).`id`))\",\r\n              \"cover (count(cover ((`d`.`c2`))))\",\r\n              \"cover (countn(cover ((`d`.`c4`))))\",\r\n              \"cover (sum(cover ((`d`.`c3`))))\",\r\n              \"cover (sum(cover ((`d`.`c4`))))\"\r\n            ],\r\n            \"index\": \"idx1\",\r\n            \"index_group_aggs\": {\r\n              \"agregados\": [\r\n                {\r\n                  \"agregado\": \"COUNT\",\r\n                  \"depende\": [\r\n                    2\r\n                  ],\r\n                  \"expr\": \"cover ((`d`.`c2`))\",\r\n                  \"id\": 6,\r\n                  \"keypos\": 2\r\n                },\r\n                {\r\n                  \"aggregate\": \"COUNTN\",\r\n                  \"depends\": [\r\n                    4\r\n                  ],\r\n                  \"expr\": \"cover ((`d`.`c4`))\",\r\n                  \"id\": 7,\r\n                  \"keypos\": 4\r\n                },\r\n                {\r\n                  \"aggregate\": \"SUM\",\r\n                  \"depende\": [\r\n                    3\r\n                  ],\r\n                  \"expr\": \"cover ((`d`.`c3`))\",\r\n                  \"id\": 8,\r\n                  \"keypos\": 3\r\n                },\r\n                {\r\n                  \"aggregate\": \"SUM\",\r\n                  \"depende\": [\r\n                    4\r\n                  ],\r\n                  \"expr\": \"cover ((`d`.`c4`))\",\r\n                  \"id\": 9,\r\n                  \"keypos\": 4\r\n                }\r\n              ],\r\n              \"depends\": [\r\n                1,\r\n                2,\r\n                3,\r\n                4\r\n              ],\r\n              \"grupo\": [\r\n                {\r\n                  \"depende\": [\r\n                    1\r\n                  ],\r\n                  \"expr\": \"cover ((`d`.`c1`))\",\r\n                  \"id\": 1,\r\n                  \"keypos\": 1\r\n                },\r\n                {\r\n                  \"depends\": [\r\n                    2\r\n                  ],\r\n                  \"expr\": \"cover ((`d`.`c2`))\",\r\n                  \"id\": 2,\r\n                  \"keypos\": 2\r\n                }\r\n              ],\r\n              \"partial\": true\r\n            },\r\n            \"index_id\": \"d06df7c5d379cd5\",\r\n            \"index_projection\": {\r\n              \"entry_keys\": [\r\n                1,\r\n                2,\r\n                6,\r\n                7,\r\n                8,\r\n                9\r\n              ]\r\n            },\r\n            \"keyspace\": \"default\",\r\n            \"namespace\": \"default\",\r\n            \"spans\": [\r\n              {\r\n                \"exact\": true\r\n                \"range\": [\r\n                  {\r\n                    \"inclusi\u00f3n\": 0,\r\n                    \"bajo\": \"0\"\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\": \"Secuencia\",\r\n              \"~children\": [\r\n                {\r\n                  \"#operator\": \"InitialGroup\",\r\n                  \"agregados\": [\r\n                    \"sum(cover (count(cover ((`d`.`c2`)))))\",\r\n                    \"sum(cover (countn(cover ((`d`.`c4`)))))\",\r\n                    \"sum(cover (sum(cover ((`d`.`c3`)))))\",\r\n                    \"sum(cover (sum(cover ((`d`.`c4`)))))\"\r\n                  ],\r\n                  \"group_keys\": [\r\n                    \"cover ((`d`.`c1`))\",\r\n                    \"cover ((`d`.`c2`))\"\r\n                  ]\r\n                }\r\n              ]\r\n            }\r\n          },\r\n          {\r\n            \"#operator\": \"IntermediateGroup\",\r\n            \"agregados\": [\r\n              \"sum(cover (count(cover ((`d`.`c2`)))))\",\r\n              \"sum(cover (countn(cover ((`d`.`c4`)))))\",\r\n              \"sum(cover (sum(cover ((`d`.`c3`)))))\",\r\n              \"sum(cover (sum(cover ((`d`.`c4`)))))\"\r\n            ],\r\n            \"group_keys\": [\r\n              \"cover ((`d`.`c1`))\",\r\n              \"cover ((`d`.`c2`))\"\r\n            ]\r\n          },\r\n          {\r\n            \"#operator\": \"FinalGroup\",\r\n            \"agregados\": [\r\n              \"sum(cover (count(cover ((`d`.`c2`)))))\",\r\n              \"sum(cover (countn(cover ((`d`.`c4`)))))\",\r\n              \"sum(cover (sum(cover ((`d`.`c3`)))))\",\r\n              \"sum(cover (sum(cover ((`d`.`c4`)))))\"\r\n            ],\r\n            \"group_keys\": [\r\n              \"cover ((`d`.`c1`))\",\r\n              \"cover ((`d`.`c2`))\"\r\n            ]\r\n          },\r\n          {\r\n            \"#operator\": \"Parallel\",\r\n            \"~child\": {\r\n              \"#operator\": \"Secuencia\",\r\n              \"~children\": [\r\n                {\r\n                  \"#operator\": \"InitialProject\",\r\n                  \"result_terms\": [\r\n                    {\r\n                      \"as\": \"c1\",\r\n                      \"expr\": \"cover ((`d`.`c1`))\"\r\n                    },\r\n                    {\r\n                      \"as\": \"c2\",\r\n                      \"expr\": \"cover ((`d`.`c2`))\"\r\n                    },\r\n                    {\r\n                      \"as\": \"sumc3\",\r\n                      \"expr\": \"sum(cover (sum(cover ((`d`.`c3`)))))\"\r\n                    },\r\n                    {\r\n                      \"as\": \"avgc4\",\r\n                      \"expr\": \"(sum(cover (sum(cover ((`d`.`c4`))))) \/ sum(cover (countn(cover ((`d`.`c4`))))))\"\r\n                    },\r\n                    {\r\n                      \"as\": \"countc2\",\r\n                      \"expr\": \"sum(cover (count(cover ((`d`.`c2`)))))\"\r\n                    }\r\n                  ]\r\n                }\r\n              ]\r\n            }\r\n          }\r\n        ]\r\n      },\r\n      {\r\n        \"#operator\": \"Order\",\r\n        \"limit\": \"2\",\r\n        \"offset\": \"1\",\r\n        \"sort_terms\": [\r\n          {\r\n            \"expr\": \"cover ((`d`.`c1`))\"\r\n          },\r\n          {\r\n            \"expr\": \"cover ((`d`.`c2`))\"\r\n          }\r\n        ]\r\n      },\r\n      {\r\n        \"#operator\": \"Offset\",\r\n        \"expr\": \"1\"\r\n      },\r\n      {\r\n        \"#operator\": \"Limit\",\r\n        \"expr\": \"2\"\r\n      },\r\n      {\r\n        \"#operator\": \"FinalProject\"\r\n      }\r\n    ]\r\n  },\r\n  \"text\": \"SELECT d.c1 AS c1, d.c2 AS c2, SUM(d.c3) AS sumc3, AVG(d.c4) AS avgc4, COUNT(d.c2) AS countc2 FROM default AS d WHERE d.c0 &gt; 0 GROUP BY d.c1, d.c2 ORDER BY d.c1, d.c2 OFFSET 1 LIMIT 2;\"\r\n}<\/pre>\n<ul>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">El \"index_group_aggs\" (l\u00edneas 24-88) en la secci\u00f3n IndexScan (es decir, \"#operator\": \"IndexScan3\") muestra la consulta utilizando la agrupaci\u00f3n y agregaci\u00f3n de \u00edndices. <\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Si la consulta utiliza agrupaci\u00f3n y agregaci\u00f3n de \u00edndices, los predicados se convierten exactamente en escaneos de rangos y se pasan al escaneo de \u00edndices como parte de los rangos, por lo que no habr\u00e1 ning\u00fan operador Filter en la explicaci\u00f3n.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\"> Como las claves del grupo por NO coinciden con las claves principales del \u00edndice, el indexador producir\u00e1 agregaciones parciales. Esto puede verse como \"partial\":true dentro de \"index_group_aggs\" en la l\u00ednea 87. El servicio de consulta realiza la fusi\u00f3n de grupos (ver l\u00edneas 119-161)<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Proyectos de indexador \"index_projection\" (l\u00edneas 91-99) que contienen claves de grupo y agregados.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Si el Indexador genera agregaciones parciales, la consulta no puede utilizar el orden del \u00edndice y requiere una ordenaci\u00f3n expl\u00edcita, y \"offset\", \"limit\" no pueden ser enviados al indexador. El plan tendr\u00e1 operadores expl\u00edcitos \"Order\", \"Offset\" y \"Limit\" (l\u00ednea 197 - 217)<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">La consulta contiene AVG(x) que se ha reescrito como SUM(x)\/COUNTN(x). COUNTN(x) s\u00f3lo cuenta cuando x es un valor num\u00e9rico.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Durante la fusi\u00f3n de grupos<\/span>\n<ul>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">MIN se convierte en MIN de MIN<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">MAX se convierte en MAX de MAX<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">SUM se convierte en SUM de SUM<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">CONTAR se convierte en SUMA de CONTAR<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">CONTN se convierte en SUMA de COUNTN<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">AVG se convierte en SUM de SUM dividido por SUM de COUNTN<\/span><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h3><span style=\"font-weight: 400\">Ejemplo 4: Agrupaci\u00f3n y agregaci\u00f3n con \u00edndice de matriz<\/span><\/h3>\n<p><span style=\"font-weight: 400\">Consideremos la consulta y el \u00edndice siguientes:<\/span><\/p>\n<pre class=\"theme:github lang:mysql decode:true\">SELECT d.c0 AS c0, d.c1 AS c1, SUM(d.c3) AS sumc3,\r\n       AVG(d.c4) AS avgc4, COUNT(DISTINCT d.c2) AS dcountc2\r\nFROM por defecto COMO d\r\nWHERE d.c0 &gt; 0 AND d.c1 &gt;= 10 AND ANY v IN d.a1 SATISFIES v.id = 3 END\r\nGROUP BY d.c0, d.c1\r\nORDER BY d.c0, d.c1\r\nOFFSET 1\r\nLIMIT 2;\r\n<\/pre>\n<p><span style=\"font-weight: 400\">\u00cdndice requerido:<\/span><\/p>\n<pre class=\"theme:github lang:mysql decode:true\">CREATE INDEX idxad1 ON default(c0, c1, DISTINCT ARRAY v.id FOR v IN a1 END, c2, c3, c4);<\/pre>\n<p><span style=\"font-weight: 400\">La consulta tiene GROUP BY y m\u00faltiples agregados, algunos de los agregados tienen el modificador DISTINCT. El predicado de la consulta tiene la cl\u00e1usula ANY y la consulta puede cubrirse mediante el \u00edndice de matriz idxad1. El predicado (d.c0 &gt; 0 AND d,c11 &gt;= 10 AND ANY v IN d.a1 SATISFIES <\/span><span style=\"font-weight: 400\">v.id <\/span><span style=\"font-weight: 400\">= 3 END ) pueden convertirse en escaneos de rango exacto y pasarse al escaneo de \u00edndice. En el caso de los \u00edndices de matrices, el indexador mantiene un elemento independiente para cada clave de \u00edndice de matriz. Para utilizar la agrupaci\u00f3n y agregaci\u00f3n de \u00edndices, el predicado SATISFIES debe tener un \u00fanico predicado de igualdad y la clave de \u00edndice de matriz debe tener el modificador DISTINCT. Por lo tanto, la combinaci\u00f3n de \u00edndice y consulta es adecuada para gestionar la agrupaci\u00f3n y agregaci\u00f3n de \u00edndices.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-4945 aligncenter\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2018\/04\/Screen-Shot-2018-04-03-at-7.05.38-PM-300x83.png\" alt=\"\" width=\"886\" height=\"245\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-7.05.38-PM-300x83.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-7.05.38-PM-1024x284.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-7.05.38-PM-768x213.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-7.05.38-PM-20x6.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-7.05.38-PM-1320x366.png 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-7.05.38-PM.png 1494w\" sizes=\"auto, (max-width: 886px) 100vw, 886px\" \/><\/p>\n<p><span style=\"font-weight: 400\">Este ejemplo es similar al ejemplo 1 excepto que utiliza un \u00edndice de matriz. El \u00e1rbol gr\u00e1fico de ejecuci\u00f3n anterior muestra el escaneo de \u00edndice (IndexScan3) realizando escaneo, agregaciones de agrupaci\u00f3n de \u00edndice, orden, desplazamiento y l\u00edmite. Se proyectan los resultados del escaneo de \u00edndice.<\/span><\/p>\n<h3><span style=\"font-weight: 400\">Ejemplo 5: Agrupaci\u00f3n y agregaci\u00f3n de la operaci\u00f3n UNNEST<\/span><\/h3>\n<p><span style=\"font-weight: 400\">Consideremos la consulta y el \u00edndice siguientes:<\/span><\/p>\n<pre class=\"theme:github lang:mysql decode:true\">SELECT v.id AS id, d.c0 AS c0, SUM(v.id) AS sumid,\r\n       AVG(d.c1) COMO avgc1\r\nFROM default COMO d UNNEST d.a1 COMO v\r\nWHERE v.id &gt; 0\r\nGROUP BY v.id, d.c0;<\/pre>\n<p><span style=\"font-weight: 400\">\u00cdndice requerido:<\/span><\/p>\n<pre class=\"theme:github lang:mysql decode:true\">CREATE INDEX idxaa1 ON default(ALL ARRAY v.id FOR v IN a1 END, c0, c1);<\/pre>\n<p><span style=\"font-weight: 400\">La consulta tiene GROUP BY y m\u00faltiples agregados. La consulta tiene UNNEST en el array d.a1 y un predicado en la clave del array (v.id &gt; 0).  El \u00edndice idxaa1 califica la consulta (para que Unnest utilice el \u00edndice de la matriz para el escaneo del \u00edndice, el \u00edndice de la matriz debe ser la clave principal y la variable de la matriz en la definici\u00f3n del \u00edndice debe coincidir con el alias UNNEST). El predicado (v.id &gt; 0) puede convertirse en escaneo de rango exacto y pasarse al escaneo de \u00edndice.  Por lo tanto, la combinaci\u00f3n de \u00edndice y consulta es adecuada para gestionar agrupaciones y agregaciones de \u00edndices.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-4944 aligncenter\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2018\/04\/Screen-Shot-2018-04-03-at-7.06.17-PM-300x101.png\" alt=\"\" width=\"864\" height=\"291\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-7.06.17-PM-300x101.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-7.06.17-PM-1024x345.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-7.06.17-PM-768x259.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-7.06.17-PM-20x7.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-7.06.17-PM-1320x445.png 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-7.06.17-PM.png 1526w\" sizes=\"auto, (max-width: 864px) 100vw, 864px\" \/><\/p>\n<p><span style=\"font-weight: 400\">El \u00e1rbol de ejecuci\u00f3n gr\u00e1fico anterior muestra el escaneo de \u00edndices (IndexScan3) realizando escaneos, agregaciones de agrupaci\u00f3n de \u00edndices. Los resultados del escaneo de \u00edndices se proyectan. El UNNEST es un tipo especial de JOIN entre el padre y cada elemento del array. <\/span><span style=\"font-weight: 400\">Por lo tanto, el UNNEST repite los campos del documento padre (d.c0, d.c1) y el <\/span><span style=\"font-weight: 400\">d.c0, dc.1<\/span><span style=\"font-weight: 400\"> referencia tendr\u00eda duplicados en comparaci\u00f3n con el original <\/span><span style=\"font-weight: 400\">d<\/span><span style=\"font-weight: 400\"> (Es necesario tenerlo en cuenta al utilizar SUM(), AVG()).<\/span><\/p>\n<h2><b>Reglas de agrupaci\u00f3n y agregaci\u00f3n de \u00edndices<\/b><\/h2>\n<p><span style=\"font-weight: 400\"> \u00a0<\/span><span style=\"font-weight: 400\">\u00a0La agrupaci\u00f3n y agregaci\u00f3n de \u00edndices se realiza por bloque de consulta, y la decisi\u00f3n de utilizar o no la agrupaci\u00f3n\/agregaci\u00f3n de \u00edndices s\u00f3lo se toma tras el proceso de selecci\u00f3n de \u00edndices.<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">El bloque de consulta no debe contener Joins, NEST, SUBconsultas.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">El bloque de consulta debe estar cubierto por un \u00edndice unifilar.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">El bloque de consulta no debe contener ARRAY_AGG()<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">El bloque de consulta no puede correlacionarse<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Todos los predicados deben traducirse exactamente en exploraciones de rangos.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Las expresiones GROUP BY y Aggregate no pueden hacer referencia a subconsultas, par\u00e1metros con nombre ni par\u00e1metros posicionales.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Claves GROUP BY, las expresiones agregadas pueden ser claves de \u00edndice, claves de documento, expresiones sobre claves de \u00edndice o expresiones sobre claves de documento.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">El \u00edndice debe ser capaz de agrupar y agregar todos los agregados en el bloque de consulta, de lo contrario no habr\u00e1 agregaci\u00f3n del \u00edndice. (es decir, ALL o None)<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">El agregado contiene el modificador DISTINCT<\/span>\n<ul>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\"> Las claves de grupo deben coincidir exactamente con las claves de \u00edndice principales (si la consulta contiene un predicado de igualdad en la clave de \u00edndice, asume que esta clave de \u00edndice se incluye impl\u00edcitamente en las claves de GRUPO si no est\u00e1 ya presente). <\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">La expresi\u00f3n agregada debe estar en una de las claves de \u00edndice principales n+1 (n representa el n\u00famero de claves de grupo).<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\"> En caso de \u00edndice de partici\u00f3n, las claves de partici\u00f3n deben coincidir exactamente con las claves de grupo.<\/span><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h2><b>Resumen<\/b><\/h2>\n<p><span style=\"font-weight: 400\">Cuando analice el plan de explicaci\u00f3n, correlacione los predicados en la explicaci\u00f3n con los rangos y aseg\u00farese de que todos los predicados se traducen exactamente a escaneos de rangos y que la consulta est\u00e1 cubierta. Aseg\u00farese de que la consulta utiliza agrupaciones y agregaciones de \u00edndices y, si es posible, utilice agregaciones completas del indexador ajustando las claves de \u00edndice para mejorar el rendimiento.<\/span><\/p>","protected":false},"excerpt":{"rendered":"<p>Couchbase N1QL is a modern query processing engine designed to provide aggregate SQL for JSON by index on distributed data with a flexible data model. Modern databases are deployed on massive clusters. Using JSON provides a flexible data mode. N1QL [&hellip;]<\/p>","protected":false},"author":7586,"featured_media":4938,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1814,1816,9417,1812],"tags":[2173,1572,2042,1505,1261,1725],"ppma_author":[9067],"class_list":["post-4935","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-application-design","category-couchbase-server","category-performance","category-n1ql-query","tag-aggregates","tag-database","tag-grouping","tag-index","tag-json","tag-nosql-database"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.8 (Yoast SEO v25.8) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>SQL Group by Index | Aggregate Index SQL | Couchbase<\/title>\n<meta name=\"description\" content=\"Index grouping and aggregations can improve query performance magnitude and reduce the latencies to make SQL for JSON query processing easier.\" \/>\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\/understanding-index-grouping-aggregation-couchbase-n1ql-query\/\" \/>\n<meta property=\"og:locale\" content=\"es_MX\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Understanding Index Grouping And Aggregation in Couchbase N1QL Query\" \/>\n<meta property=\"og:description\" content=\"Index grouping and aggregations can improve query performance magnitude and reduce the latencies to make SQL for JSON query processing easier.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/es\/understanding-index-grouping-aggregation-couchbase-n1ql-query\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2018-04-04T02:31:02+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T06:43:08+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-10.08.36-AM.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1388\" \/>\n\t<meta property=\"og:image:height\" content=\"744\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Sitaram Vemulapalli\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Sitaram Vemulapalli\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"21 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/understanding-index-grouping-aggregation-couchbase-n1ql-query\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/understanding-index-grouping-aggregation-couchbase-n1ql-query\/\"},\"author\":{\"name\":\"Sitaram Vemulapalli\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/ead1d6aa77984d26b03977adca6f174f\"},\"headline\":\"Understanding Index Grouping And Aggregation in Couchbase N1QL Query\",\"datePublished\":\"2018-04-04T02:31:02+00:00\",\"dateModified\":\"2025-06-14T06:43:08+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/understanding-index-grouping-aggregation-couchbase-n1ql-query\/\"},\"wordCount\":2976,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/understanding-index-grouping-aggregation-couchbase-n1ql-query\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-10.08.36-AM.png\",\"keywords\":[\"aggregates\",\"database\",\"grouping\",\"Index\",\"JSON\",\"NoSQL Database\"],\"articleSection\":[\"Application Design\",\"Couchbase Server\",\"High Performance\",\"SQL++ \/ N1QL Query\"],\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/understanding-index-grouping-aggregation-couchbase-n1ql-query\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/understanding-index-grouping-aggregation-couchbase-n1ql-query\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/understanding-index-grouping-aggregation-couchbase-n1ql-query\/\",\"name\":\"SQL Group by Index | Aggregate Index SQL | Couchbase\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/understanding-index-grouping-aggregation-couchbase-n1ql-query\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/understanding-index-grouping-aggregation-couchbase-n1ql-query\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-10.08.36-AM.png\",\"datePublished\":\"2018-04-04T02:31:02+00:00\",\"dateModified\":\"2025-06-14T06:43:08+00:00\",\"description\":\"Index grouping and aggregations can improve query performance magnitude and reduce the latencies to make SQL for JSON query processing easier.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/understanding-index-grouping-aggregation-couchbase-n1ql-query\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/understanding-index-grouping-aggregation-couchbase-n1ql-query\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/understanding-index-grouping-aggregation-couchbase-n1ql-query\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-10.08.36-AM.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-10.08.36-AM.png\",\"width\":1388,\"height\":744},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/understanding-index-grouping-aggregation-couchbase-n1ql-query\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Understanding Index Grouping And Aggregation in Couchbase N1QL Query\"}]},{\"@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\/ead1d6aa77984d26b03977adca6f174f\",\"name\":\"Sitaram Vemulapalli\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/988725d1a67be1227a105a4071c69e2b\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/67edc83f4123b955cf7c20e1c509799b94a1fb14d1aedb3c226b998081714da3?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/67edc83f4123b955cf7c20e1c509799b94a1fb14d1aedb3c226b998081714da3?s=96&d=mm&r=g\",\"caption\":\"Sitaram Vemulapalli\"},\"description\":\"Sitaram Vemulapalli is a Principal Software Engineer at Couchbase. Prior to Couchbase, he served as an architect for IBM Informix SQL and has more than 20 years experience in database design and development. Sitaram holds a master's degree in system science and automation from the Indian Institute of Science, India.\",\"url\":\"https:\/\/www.couchbase.com\/blog\/es\/author\/sitaram-vemulapallicouchbase-com\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"SQL Group by Index | Aggregate Index SQL | Couchbase","description":"Index grouping and aggregations can improve query performance magnitude and reduce the latencies to make SQL for JSON query processing easier.","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\/understanding-index-grouping-aggregation-couchbase-n1ql-query\/","og_locale":"es_MX","og_type":"article","og_title":"Understanding Index Grouping And Aggregation in Couchbase N1QL Query","og_description":"Index grouping and aggregations can improve query performance magnitude and reduce the latencies to make SQL for JSON query processing easier.","og_url":"https:\/\/www.couchbase.com\/blog\/es\/understanding-index-grouping-aggregation-couchbase-n1ql-query\/","og_site_name":"The Couchbase Blog","article_published_time":"2018-04-04T02:31:02+00:00","article_modified_time":"2025-06-14T06:43:08+00:00","og_image":[{"width":1388,"height":744,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-10.08.36-AM.png","type":"image\/png"}],"author":"Sitaram Vemulapalli","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Sitaram Vemulapalli","Est. reading time":"21 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/understanding-index-grouping-aggregation-couchbase-n1ql-query\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/understanding-index-grouping-aggregation-couchbase-n1ql-query\/"},"author":{"name":"Sitaram Vemulapalli","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/ead1d6aa77984d26b03977adca6f174f"},"headline":"Understanding Index Grouping And Aggregation in Couchbase N1QL Query","datePublished":"2018-04-04T02:31:02+00:00","dateModified":"2025-06-14T06:43:08+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/understanding-index-grouping-aggregation-couchbase-n1ql-query\/"},"wordCount":2976,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/understanding-index-grouping-aggregation-couchbase-n1ql-query\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-10.08.36-AM.png","keywords":["aggregates","database","grouping","Index","JSON","NoSQL Database"],"articleSection":["Application Design","Couchbase Server","High Performance","SQL++ \/ N1QL Query"],"inLanguage":"es","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/understanding-index-grouping-aggregation-couchbase-n1ql-query\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/understanding-index-grouping-aggregation-couchbase-n1ql-query\/","url":"https:\/\/www.couchbase.com\/blog\/understanding-index-grouping-aggregation-couchbase-n1ql-query\/","name":"SQL Group by Index | Aggregate Index SQL | Couchbase","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/understanding-index-grouping-aggregation-couchbase-n1ql-query\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/understanding-index-grouping-aggregation-couchbase-n1ql-query\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-10.08.36-AM.png","datePublished":"2018-04-04T02:31:02+00:00","dateModified":"2025-06-14T06:43:08+00:00","description":"Index grouping and aggregations can improve query performance magnitude and reduce the latencies to make SQL for JSON query processing easier.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/understanding-index-grouping-aggregation-couchbase-n1ql-query\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/understanding-index-grouping-aggregation-couchbase-n1ql-query\/"]}]},{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/understanding-index-grouping-aggregation-couchbase-n1ql-query\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-10.08.36-AM.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/04\/Screen-Shot-2018-04-03-at-10.08.36-AM.png","width":1388,"height":744},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/understanding-index-grouping-aggregation-couchbase-n1ql-query\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Understanding Index Grouping And Aggregation in Couchbase N1QL Query"}]},{"@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\/ead1d6aa77984d26b03977adca6f174f","name":"Sitaram Vemulapalli","image":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/988725d1a67be1227a105a4071c69e2b","url":"https:\/\/secure.gravatar.com\/avatar\/67edc83f4123b955cf7c20e1c509799b94a1fb14d1aedb3c226b998081714da3?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/67edc83f4123b955cf7c20e1c509799b94a1fb14d1aedb3c226b998081714da3?s=96&d=mm&r=g","caption":"Sitaram Vemulapalli"},"description":"Sitaram Vemulapalli es ingeniero de software principal en Couchbase. Antes de trabajar en Couchbase, fue arquitecto de IBM Informix SQL y tiene m\u00e1s de 20 a\u00f1os de experiencia en dise\u00f1o y desarrollo de bases de datos. Sitaram tiene un m\u00e1ster en ciencia de sistemas y automatizaci\u00f3n por el Instituto Indio de Ciencias de la India.","url":"https:\/\/www.couchbase.com\/blog\/es\/author\/sitaram-vemulapallicouchbase-com\/"}]}},"authors":[{"term_id":9067,"user_id":7586,"is_guest":0,"slug":"sitaram-vemulapallicouchbase-com","display_name":"Sitaram Vemulapalli","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/67edc83f4123b955cf7c20e1c509799b94a1fb14d1aedb3c226b998081714da3?s=96&d=mm&r=g","author_category":"","last_name":"Vemulapalli","first_name":"Sitaram","job_title":"","user_url":"","description":"Sitaram Vemulapalli es ingeniero de software principal en Couchbase. Antes de trabajar en Couchbase, fue arquitecto de IBM Informix SQL y tiene m\u00e1s de 20 a\u00f1os de experiencia en dise\u00f1o y desarrollo de bases de datos. Sitaram tiene un m\u00e1ster en ciencia de sistemas y automatizaci\u00f3n por el Instituto Indio de Ciencias de la India."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/4935","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\/7586"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/comments?post=4935"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/4935\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/media\/4938"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/media?parent=4935"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/categories?post=4935"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/tags?post=4935"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/ppma_author?post=4935"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}