{"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\/pt\/understanding-index-grouping-aggregation-couchbase-n1ql-query\/","title":{"rendered":"Entendendo o agrupamento e a agrega\u00e7\u00e3o de \u00edndices na consulta N1QL do Couchbase"},"content":{"rendered":"<p><a href=\"https:\/\/www.couchbase.com\/blog\/pt\/\"><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\"> \u00e9 um mecanismo moderno de processamento de consultas projetado para fornecer SQL agregado para JSON por \u00edndice em dados distribu\u00eddos com um modelo de dados flex\u00edvel. Os bancos de dados modernos s\u00e3o implantados em clusters enormes. O uso do JSON oferece um modo de dados flex\u00edvel. O N1QL oferece suporte a SQL aprimorado de grupo por \u00edndice para JSON para facilitar o processamento de consultas.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Os aplicativos e drivers de banco de dados enviam a consulta N1QL a um dos n\u00f3s de consulta dispon\u00edveis em um cluster. O n\u00f3 de consulta analisa a consulta e usa metadados em objetos subjacentes para descobrir o plano de execu\u00e7\u00e3o ideal, que \u00e9 ent\u00e3o executado. Durante a execu\u00e7\u00e3o, dependendo da consulta, usando os \u00edndices aplic\u00e1veis, o n\u00f3 de consulta trabalha com os n\u00f3s de \u00edndice e de dados para recuperar dados e realizar as opera\u00e7\u00f5es planejadas. Como o Couchbase \u00e9 um banco de dados modular em cluster, voc\u00ea dimensiona os servi\u00e7os de dados, \u00edndice e consulta para atender \u00e0s suas metas de desempenho e disponibilidade.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Antes do Couchbase 5.5, mesmo quando uma consulta com GROUP BY e\/ou agregados era coberta por um \u00edndice, a consulta buscava todos os dados relevantes do indexador e executava o agrupamento\/agrega\u00e7\u00e3o dos dados no mecanismo de consulta.<\/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\">No Couchbase 5.5, o planejador de consultas foi aprimorado para solicitar de forma inteligente que o indexador execute o agrupamento e a agrega\u00e7\u00e3o, al\u00e9m da varredura de intervalo <\/span><b>para o \u00edndice de cobertura<\/b><span style=\"font-weight: 400\">. O Indexador foi aprimorado para executar agrupamento, COUNT(), SUM(), MIN(), MAX(), AVG() e opera\u00e7\u00f5es relacionadas em tempo real. \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\">Isso n\u00e3o requer altera\u00e7\u00f5es na consulta do usu\u00e1rio, mas \u00e9 necess\u00e1rio um bom projeto de \u00edndice para cobrir a consulta e ordenar as chaves do \u00edndice.  Nem toda consulta se beneficiar\u00e1 dessa otimiza\u00e7\u00e3o, e nem todo \u00edndice pode acelerar todas as opera\u00e7\u00f5es de agrupamento e agrega\u00e7\u00e3o. A compreens\u00e3o dos padr\u00f5es corretos o ajudar\u00e1 a projetar seus \u00edndices e consultas. O agrupamento e a agrega\u00e7\u00e3o de \u00edndices no \u00edndice secund\u00e1rio global s\u00e3o compat\u00edveis com os dois mecanismos de armazenamento: GSI padr\u00e3o e GSI otimizado para mem\u00f3ria (MOI). O agrupamento e a agrega\u00e7\u00e3o de \u00edndices s\u00e3o compat\u00edveis somente com a Enterprise Edition.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Essa etapa de redu\u00e7\u00e3o da execu\u00e7\u00e3o de GROUP BY e Aggregation pelo indexador reduz a quantidade de transfer\u00eancia de dados e E\/S de disco, resultando em:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Melhoria no tempo de resposta da consulta<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Melhor utiliza\u00e7\u00e3o dos recursos<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Baixa lat\u00eancia<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Alta escalabilidade<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Baixo custo total de propriedade<\/span><\/li>\n<\/ul>\n<h2><b>Desempenho<\/b><\/h2>\n<p><span style=\"font-weight: 400\">O agrupamento e as agrega\u00e7\u00f5es de \u00edndices podem melhorar o desempenho da consulta em ordens de magnitude e reduzir drasticamente as lat\u00eancias. A tabela a seguir lista alguns exemplos de medi\u00e7\u00f5es de lat\u00eancia de consulta.<\/span><\/p>\n<p><span style=\"font-weight: 400\">\u00cdndice :<\/span><\/p>\n<pre class=\"theme:github lang:mysql decode:true\">CREATE INDEX idx_ts_type_country_city ON `travel-sample` (type, country, city);<\/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\">Descri\u00e7\u00e3o<\/span><\/td>\n<td><span style=\"font-weight: 400\">5.0 Lat\u00eancias <\/span><\/td>\n<td><span style=\"font-weight: 400\">5.5 Lat\u00eancias<\/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 chave de \u00edndice principal <\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Agrega\u00e7\u00e3o <\/span><\/li>\n<\/ul>\n<\/td>\n<td><span style=\"font-weight: 400\">230ms<\/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 city) AS cntdcity <\/span><span style=\"font-weight: 400\">FROM `travel-sample` AS t <\/span><span style=\"font-weight: 400\">WHERE t.type IN [\"hotel\", \"airport\"] <\/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 v\u00e1rias chaves de \u00edndice principais<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">V\u00e1rios agregados<\/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.country, COUNT(city) AS cnt <\/span><span style=\"font-weight: 400\">FROM `travel-sample` AS t\u00a0<\/span><span style=\"font-weight: 400\">ONDE <\/span><b>t.type = \"airport\" (aeroporto) <\/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 primeira chave de \u00edndice principal n\u00e3o igualit\u00e1ria<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Agrega\u00e7\u00e3o<\/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.city, 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.city <\/span><span style=\"font-weight: 400\">LETTING cnt = COUNT(city) <\/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 chave de \u00edndice n\u00e3o principal<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">cl\u00e1usula de arrendamento<\/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\">300ms<\/span><\/td>\n<td><span style=\"font-weight: 400\">160ms<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<h2><b>Vis\u00e3o geral do agrupamento e da agrega\u00e7\u00e3o 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\">A figura acima mostra todas as fases poss\u00edveis pelas quais uma consulta SELECT passa para retornar os resultados. <\/span><span style=\"font-weight: 400\">\u00a0<\/span><span style=\"font-weight: 400\">O processo de filtragem usa o espa\u00e7o-chave inicial e produz um subconjunto ideal dos documentos nos quais a consulta est\u00e1 interessada. Para produzir o menor subconjunto poss\u00edvel, os \u00edndices s\u00e3o usados para aplicar o maior n\u00famero poss\u00edvel de predicados. O predicado da consulta indica o subconjunto de dados de interesse. Durante a fase de planejamento da consulta, selecionamos os \u00edndices a serem usados. Em seguida, para cada \u00edndice, decidimos os predicados a serem aplicados por cada \u00edndice. Os predicados da consulta s\u00e3o traduzidos em varreduras de intervalo no plano de consulta e passados para o Indexador. <\/span><\/p>\n<p><span style=\"font-weight: 400\">Se a consulta n\u00e3o tiver JOINs e for coberta pelo \u00edndice, as fases Fetch e Join poder\u00e3o ser eliminadas.<\/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\">Quando todos os predicados s\u00e3o traduzidos exatamente para varreduras de intervalo, a fase de filtro tamb\u00e9m pode ser eliminada. Nessa situa\u00e7\u00e3o, a varredura e os agregados est\u00e3o lado a lado e, como o indexador tem a capacidade de fazer agrega\u00e7\u00e3o, essa fase pode ser feita no n\u00f3 do indexador. Em alguns casos, as fases Sort, Offset e Limit tamb\u00e9m podem ser feitas no n\u00f3 do 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\">O fluxograma a seguir descreve como o planejador de consultas decide executar a agrega\u00e7\u00e3o de \u00edndices para cada bloco de consulta da consulta. Se a agrega\u00e7\u00e3o do \u00edndice n\u00e3o for poss\u00edvel, as agrega\u00e7\u00f5es ser\u00e3o feitas no mecanismo de consulta.<\/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 a consulta: <\/span><\/p>\n<pre class=\"theme:github lang:mysql decode:true\">SELECT type, COUNT(type)\r\nFROM `travel-sample`\r\nWHERE type IS NOT MISSING\r\nGROUP BY type;<\/pre>\n<p><span style=\"font-weight: 400\">Antes da vers\u00e3o 5.5 do Couchbase, esse mecanismo de consulta buscava dados relevantes do indexador, e o agrupamento e a agrega\u00e7\u00e3o dos dados eram feitos no mecanismo de consulta. Essa consulta simples leva cerca de 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\">Agora, na vers\u00e3o 5.5 do Couchbase, essa consulta usa o mesmo \u00edndice def_type, mas \u00e9 executada em menos de 20 ms. Na explica\u00e7\u00e3o abaixo, voc\u00ea pode ver menos etapas e a aus\u00eancia da etapa de agrupamento ap\u00f3s a varredura do \u00edndice, porque a etapa de varredura do \u00edndice tamb\u00e9m faz o agrupamento e a agrega\u00e7\u00e3o.<\/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\">\u00c0 medida que a complexidade dos dados e das consultas aumenta, o benef\u00edcio do desempenho (lat\u00eancia e taxa de transfer\u00eancia) tamb\u00e9m aumenta. \u00a0\u00a0<\/span><\/p>\n<h2><b>Entendendo o EXPLAIN de agrupamento e agrega\u00e7\u00e3o de \u00edndices<\/b><\/h2>\n<p><span style=\"font-weight: 400\">Observando a explica\u00e7\u00e3o da consulta:<\/span><\/p>\n<pre class=\"theme:github lang:mysql decode:true\">EXPLAIN SELECT type, COUNT(type) FROM `travel-sample` 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 ((`travel-sample`.`type`))\",\r\n          \"cover ((meta(`travel-sample`).`id`))\",\r\n          \"cover (count(cover ((`travel-sample`.`type`))))\"\r\n        ],\r\n        \"index\": \"def_type\",\r\n        \"index_group_aggs\": {\r\n          \"aggregates\": [\r\n            {\r\n              \"aggregate\": \"COUNT\",\r\n              \"depends\": [\r\n                0\r\n              ],\r\n              \"expr\": \"cover ((`travel-sample`.`type`))\",\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              \"depends\": [\r\n                0\r\n              ],\r\n              \"expr\": \"cover ((`travel-sample`.`type`))\",\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\": \"travel-sample\",\r\n        \"namespace\": \"default\",\r\n        \"spans\": [\r\n          {\r\n            \"exact\": true,\r\n            \"range\": [\r\n              {\r\n                \"inclusion\": 1,\r\n                \"low\": \"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\": \"Sequence\",\r\n          \"~children\": [\r\n            {\r\n              \"#operator\": \"InitialProject\",\r\n              \"result_terms\": [\r\n                {\r\n                  \"expr\": \"cover ((`travel-sample`.`type`))\"\r\n                },\r\n                {\r\n                  \"expr\": \"cover (count(cover ((`travel-sample`.`type`))))\"\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 `travel-sample` WHERE type IS NOT MISSING GROUP BY type;\"\r\n}<\/pre>\n<p>Voc\u00ea ver\u00e1 \"index_group_aggs\" na se\u00e7\u00e3o IndexScan (ou seja, \"#operator\": \"IndexScan3\"). Se \"index_group_aggs\" estiver faltando, o servi\u00e7o de consulta est\u00e1 executando agrupamento e agrega\u00e7\u00e3o. Se a consulta presente estiver usando agrupamento e agrega\u00e7\u00e3o de \u00edndices e tiver todas as informa\u00e7\u00f5es relevantes, o indexador precisar\u00e1 fazer o agrupamento e a agrega\u00e7\u00e3o. A tabela a seguir descreve como interpretar as v\u00e1rias informa\u00e7\u00f5es do objeto index_group_aggs.<\/p>\n<div class=\"responsive-table\">\n<table>\n<tbody>\n<tr>\n<td><b>Nome do campo<\/b><\/td>\n<td><b>Descri\u00e7\u00e3o<\/b><\/td>\n<td><b>N\u00fameros de linha do exemplo<\/b><\/td>\n<td><b>Explicar o texto em um exemplo<\/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, e cada objeto representa um agregado. A aus\u00eancia desse item significa que apenas group by est\u00e1 presente na consulta.<\/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\">Opera\u00e7\u00e3o 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\">CONTAGEM<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\">distinto<\/span><\/td>\n<td><span style=\"font-weight: 400\">O modificador agregado \u00e9 DISTINCT<\/span><\/td>\n<td><span style=\"font-weight: 400\">&#8211;<\/span><\/td>\n<td><span style=\"font-weight: 400\">False(Quando verdadeiro, somente ele 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 posi\u00e7\u00f5es de chave de \u00edndice (come\u00e7ando com 0) das quais a express\u00e3o agregada depende.<\/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 type \u00e9 a 0\u00aa chave de \u00edndice do \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\">express\u00e3o 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 exclusivo fornecido internamente e que ser\u00e1 usado em <\/span><span style=\"font-weight: 400\">index_projection<\/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\u00a0teclas<\/span><\/td>\n<td><span style=\"font-weight: 400\">O c\u00f3digo para isso indica o uso da express\u00e3o na posi\u00e7\u00e3o da chave de \u00edndice ou do campo expr.<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Um valor &gt; -1 significa que a express\u00e3o agregada corresponde exatamente \u00e0 posi\u00e7\u00e3o da chave de \u00edndice correspondente (come\u00e7ando com 0).<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Um valor de -1 significa que a express\u00e3o de agrega\u00e7\u00e3o ] n\u00e3o corresponde exatamente \u00e0 posi\u00e7\u00e3o da chave de \u00edndice e usa a express\u00e3o do 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 type \u00e9 a 0\u00aa chave de \u00edndice do \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 posi\u00e7\u00f5es-chave de \u00edndice das quais as express\u00f5es de grupos\/agregados dependem (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, e cada objeto representa uma chave de grupo. A aus\u00eancia desse item significa que n\u00e3o h\u00e1 cl\u00e1usula GROUP BY presente na 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 posi\u00e7\u00f5es de chave de \u00edndice (come\u00e7ando com 0) das quais a express\u00e3o de grupo depende.<\/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 o tipo \u00e9 a 0\u00aa chave da chave do \u00edndice do \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\">express\u00e3o 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 exclusivo fornecido internamente e que ser\u00e1 usado em <\/span><span style=\"font-weight: 400\">index_projection.<\/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\u00a0teclas<\/span><\/td>\n<td><span style=\"font-weight: 400\">O c\u00f3digo para isso indica o uso da express\u00e3o na posi\u00e7\u00e3o da chave de \u00edndice ou do campo expr.<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Um valor &gt; -1 significa que a express\u00e3o do grupo corresponde exatamente \u00e0 posi\u00e7\u00e3o da chave de \u00edndice correspondente (come\u00e7ando com 0).<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Um valor de -1 significa que a chave de grupo n\u00e3o corresponde exatamente \u00e0 posi\u00e7\u00e3o da chave de \u00edndice e usa a express\u00e3o do 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 type \u00e9 a 0\u00aa chave de \u00edndice do \u00edndice def_type)<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p><span style=\"font-weight: 400\">O campo covers \u00e9 uma matriz e tem todas as chaves de \u00edndice, chave de documento (META().id), express\u00f5es de chaves de grupo que n\u00e3o correspondem exatamente \u00e0s chaves de \u00edndice (classificadas por id), agregados classificados por id. Al\u00e9m disso, \"Index_projection\" ter\u00e1 todos os ids de grupo\/agregado.<\/span><\/p>\n<pre class=\"theme:github lang:mysql decode:true\">\"covers\": [\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"cover ((`travel-sample`.`type`))\", \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u2190 Index key (0)\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"cover ((meta(`travel-sample`).`id`))\", \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u2190 document key (1)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"cover (count(cover ((`travel-sample`.`type`))))\" \u00a0\u00a0\u00a0\u00a0\u2190 aggregate (2)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0]<\/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>Detalhes de <\/b><b>Agrupamento e agrega\u00e7\u00e3o de \u00edndices<\/b><\/h2>\n<p><span style=\"font-weight: 400\">Usaremos exemplos para mostrar como funcionam o agrupamento e as agrega\u00e7\u00f5es de \u00edndices. Para seguir os exemplos <\/span><span style=\"font-weight: 400\">crie um bucket \"default\" e insira os seguintes documentos:<\/span><\/p>\n<pre class=\"theme:github lang:mysql decode:true\">INSERT INTO default (KEY,VALUE)\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    VALUES (\"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    VALUES (\"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    VALUES (\"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    VALUES (\"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    VALUES (\"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    VALUES (\"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\">Exemplo 1: Agrupar por chaves de \u00edndice principais<\/span><\/h3>\n<p><span style=\"font-weight: 400\">Vamos considerar a consulta e o \u00edndice a seguir:<\/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 default AS 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 necess\u00e1rio:<\/p>\n<pre class=\"theme:github lang:mysql decode:true\">CREATE INDEX idx1 ON default(c0, c1, c2, c3, c4);<\/pre>\n<p><span style=\"font-weight: 400\">\u00a0 \u00a0 \u00a0A consulta tem GROUP BY e v\u00e1rios agregados, alguns dos agregados t\u00eam o modificador DISTINCT. A consulta pode ser coberta pelo \u00edndice idx1 e o predicado (d.c0 &gt; 0) pode ser convertido em uma varredura de intervalo exata e passado para a varredura de \u00edndice. Portanto, a combina\u00e7\u00e3o de \u00edndice e consulta qualifica o agrupamento e as agrega\u00e7\u00f5es de \u00edndice.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Os \u00edndices s\u00e3o naturalmente ordenados e agrupados pela ordem da defini\u00e7\u00e3o da chave do \u00edndice. Na consulta acima, as chaves GROUP BY (d.c0, d.c1) correspondem exatamente \u00e0s chaves principais (c0, c1) do \u00edndice. Portanto, o \u00edndice tem cada grupo de dados juntos, o indexador produzir\u00e1 uma linha por grupo, ou seja, agrega\u00e7\u00e3o completa.  Al\u00e9m disso, a consulta tem um agregado que tem o modificador DISTINCT e corresponde exatamente a uma das chaves de \u00edndice com posi\u00e7\u00e3o menor ou igual ao n\u00famero de chaves de grupo mais um (ou seja, h\u00e1 2 chaves de grupo, o modificador DISTINCT pode ser qualquer uma das chaves de \u00edndice na posi\u00e7\u00e3o 0,1,2 porque a chave de \u00edndice seguida pelas chaves de grupo e o modificador DISTINCT pode ser aplicado sem ordena\u00e7\u00e3o). Portanto, a consulta acima \u00e9 adequada para o indexador lidar com o agrupamento e a agrega\u00e7\u00e3o. <\/span><\/p>\n<p><span style=\"font-weight: 400\">Se o grupo n\u00e3o tiver uma das principais chaves de \u00edndice e houver um predicado de igualdade, ser\u00e1 feita uma otimiza\u00e7\u00e3o especial, tratando a chave de \u00edndice implicitamente presente nas chaves de grupo e determinando se a agrega\u00e7\u00e3o completa \u00e9 poss\u00edvel ou n\u00e3o. Para o \u00edndice de parti\u00e7\u00e3o, todas as chaves de parti\u00e7\u00e3o precisam estar presentes nas chaves de grupo para gerar agrega\u00e7\u00f5es 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\">A \u00e1rvore de execu\u00e7\u00e3o gr\u00e1fica acima mostra a varredura de \u00edndice (IndexScan3) realizando varreduras e agrega\u00e7\u00f5es de agrupamento de \u00edndices. Os resultados da varredura de \u00edndice s\u00e3o projetados.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Vamos dar uma olhada no texto para explicar:<\/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              \"cover ((`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(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              \"aggregates\": [\r\n                {\r\n                  \"aggregate\": \"COUNT\",\r\n                  \"depends\": [\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                  \"depends\": [\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                  \"depends\": [\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              \"group\": [\r\n                {\r\n                  \"depends\": [\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                    \"inclusion\": 0,\r\n                    \"low\": \"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\">O \"index_group_aggs\" (linhas 24-89) na se\u00e7\u00e3o IndexScan (ou seja, \"#operator\": \"IndexScan3\") mostra a consulta usando agrupamento e agrega\u00e7\u00f5es de \u00edndices. <\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Se a consulta usar agrupamento e agrega\u00e7\u00e3o de \u00edndice, os predicados ser\u00e3o convertidos exatamente em varreduras de intervalo e passados para a varredura de \u00edndice como parte dos intervalos, portanto, n\u00e3o haver\u00e1 nenhum operador Filter na explica\u00e7\u00e3o.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\"> Como as chaves de agrupamento por correspondem exatamente \u00e0s chaves de \u00edndice principais, o indexador produzir\u00e1 agrega\u00e7\u00f5es completas. Portanto, tamb\u00e9m eliminamos o agrupamento no servi\u00e7o de consulta (n\u00e3o h\u00e1 operadores InitialGroup, IntermediateGroup, FinalGroup na explica\u00e7\u00e3o). <\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">O indexador projeta \"index_projection\" (linhas 99-107), incluindo todas as chaves de grupo e agregados.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Se a consulta ORDER BY corresponder \u00e0s chaves de \u00edndice principais e GROUP BY estiver nas chaves de \u00edndice principais, poderemos usar a ordem de \u00edndice. Isso pode ser encontrado em explain (linhas 91-98) e n\u00e3o usar\u00e1 o \"#operator\": \"Order\" entre a linha 164-165. \u00a0<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Como a consulta pode usar a ordem do \u00edndice e n\u00e3o h\u00e1 cl\u00e1usula HAVING na consulta, os valores \"offset\" e \"limit\" podem ser passados para o indexador. <\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Isso pode ser encontrado na linha 112, 110. O \"offset\" s\u00f3 pode ser aplicado uma vez que voc\u00ea n\u00e3o ver\u00e1 o \"#operator\": \"Offset\" entre as linhas 164-165, mas a reaplica\u00e7\u00e3o de \"limit\" n\u00e3o \u00e9 poss\u00edvel. Isso pode ser visto na linha 165-168.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">A consulta cont\u00e9m AVG(x) e foi reescrita como SUM(x)\/COUNTN(x). O COUNTN(x) s\u00f3 conta quando x \u00e9 um valor num\u00e9rico.<\/span><\/li>\n<\/ul>\n<h3><span style=\"font-weight: 400\">Exemplo 2: Agrupar por chaves de \u00edndice principais, LETTING, HAVING <\/span><\/h3>\n<p><span style=\"font-weight: 400\">Vamos considerar a consulta e o \u00edndice a seguir:<\/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 default AS 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 necess\u00e1rio:<\/span><\/p>\n<pre class=\"theme:github lang:mysql decode:true\">CREATE INDEX idx1 ON default(c0, c1, c2, c3, c4);<\/pre>\n<p><span style=\"font-weight: 400\">A consulta acima \u00e9 semelhante ao Exemplo 1, mas tem as cl\u00e1usulas LETTING e HAVING. O indexador n\u00e3o ser\u00e1 capaz de lidar com elas e, portanto, as cl\u00e1usulas LETTING e HAVING s\u00e3o aplicadas no servi\u00e7o de consulta ap\u00f3s o agrupamento e as agrega\u00e7\u00f5es. Portanto, voc\u00ea v\u00ea os operadores Let e Filter ap\u00f3s o IndexScan3 na \u00e1rvore de execu\u00e7\u00e3o. A cl\u00e1usula Having \u00e9 um filtro e elimina ainda mais itens, portanto, \"offset\" e \"limit\" n\u00e3o podem ser enviados ao indexador e precisam ser aplicados no servi\u00e7o de consulta, mas ainda podemos usar a ordem do \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\">Exemplo 3: Agrupar por chaves de \u00edndice n\u00e3o principais<\/span><\/h3>\n<p><span style=\"font-weight: 400\">Vamos considerar a consulta e o \u00edndice a seguir:<\/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) AS avgc4, COUNT(d.c2) AS countc2\r\nFROM default AS 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 necess\u00e1rio:<\/span><\/p>\n<pre class=\"theme:github lang:mysql decode:true\">CREATE INDEX idx1 ON 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\">A consulta tem GROUP BY e v\u00e1rios agregados. A consulta pode ser coberta pelo \u00edndice idx1 e o predicado (d.c0 &gt; 0) pode ser convertido em uma varredura de intervalo exata e passado para a varredura de \u00edndice. Portanto, a combina\u00e7\u00e3o de \u00edndice e consulta qualifica o agrupamento e as agrega\u00e7\u00f5es do \u00edndice.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Na consulta acima, as chaves GROUP BY (d.c1, d.c2) N\u00c3O correspondem \u00e0s chaves principais (c0, c1) do \u00edndice. Os grupos est\u00e3o espalhados pelo \u00edndice. Portanto, o indexador produzir\u00e1 v\u00e1rias linhas para cada grupo, ou seja, agrega\u00e7\u00e3o parcial. No caso da agrega\u00e7\u00e3o parcial, o servi\u00e7o de consulta faz a mesclagem de grupos, a consulta n\u00e3o pode usar a ordem do \u00edndice nem enviar \"offset\", \"limit\" ao indexador.  No caso de agrega\u00e7\u00e3o parcial, se algum agregado tiver o modificador DISTINCT, o agrupamento de \u00edndices e a agrega\u00e7\u00e3o n\u00e3o ser\u00e3o poss\u00edveis. A consulta acima \u00e9 adequada para o indexador lidar com o agrupamento e a agrega\u00e7\u00e3o. <\/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\">A \u00e1rvore de execu\u00e7\u00e3o gr\u00e1fica acima mostra a varredura de \u00edndice (IndexScan3) realizando agrega\u00e7\u00f5es de varredura e agrupamento de \u00edndices. Os resultados da varredura de \u00edndice s\u00e3o agrupados novamente e projetados.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Vamos dar uma olhada no texto para explicar:<\/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              \"cover ((`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              \"aggregates\": [\r\n                {\r\n                  \"aggregate\": \"COUNT\",\r\n                  \"depends\": [\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                  \"depends\": [\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                  \"depends\": [\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              \"group\": [\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                  \"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                    \"inclusion\": 0,\r\n                    \"low\": \"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\": \"Sequence\",\r\n              \"~children\": [\r\n                {\r\n                  \"#operator\": \"InitialGroup\",\r\n                  \"aggregates\": [\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            \"aggregates\": [\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            \"aggregates\": [\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\": \"Sequence\",\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\">O \"index_group_aggs\" (linhas 24-88) na se\u00e7\u00e3o IndexScan (ou seja, \"#operator\": \"IndexScan3\") mostra a consulta usando agrupamento e agrega\u00e7\u00f5es de \u00edndices. <\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Se a consulta usar agrupamento e agrega\u00e7\u00e3o de \u00edndice, os predicados ser\u00e3o convertidos exatamente em varreduras de intervalo e passados para a varredura de \u00edndice como parte dos intervalos, portanto, n\u00e3o haver\u00e1 nenhum operador Filter na explica\u00e7\u00e3o.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\"> Como as chaves de grupo por N\u00c3O correspondem \u00e0s chaves de \u00edndice principais, o indexador produzir\u00e1 agrega\u00e7\u00f5es parciais. Isso pode ser visto como \"partial\":true dentro de \"index_group_aggs\" na linha 87. O servi\u00e7o de consulta faz a fus\u00e3o de grupos (consulte a linha 119-161)<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Projetos de indexador \"index_projection\" (linhas 91-99) contendo chaves de grupo e agregados.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Se o indexador gerar agrega\u00e7\u00f5es parciais, a consulta n\u00e3o poder\u00e1 usar a ordem do \u00edndice e exigir\u00e1 classifica\u00e7\u00e3o expl\u00edcita, e \"offset\" e \"limit\" n\u00e3o poder\u00e3o ser enviados ao indexador. O plano ter\u00e1 os operadores expl\u00edcitos \"Order\", \"Offset\" e \"Limit\" (linha 197 - 217)<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">A consulta cont\u00e9m AVG(x) que foi reescrito como SUM(x)\/COUNTN(x). O COUNTN(x) s\u00f3 conta quando x \u00e9 um valor num\u00e9rico.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Durante a fus\u00e3o do grupo<\/span>\n<ul>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">MIN se torna MIN de MIN<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">MAX se torna MAX de MAX<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">SUM se torna SUM de SUM<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">COUNT se torna SUM de COUNT<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">CONTN se torna SUM de COUNTN<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">AVG se torna SUM de SUM dividido por SUM de COUNTN<\/span><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h3><span style=\"font-weight: 400\">Exemplo 4: Grupo e agrega\u00e7\u00e3o com \u00edndice de matriz<\/span><\/h3>\n<p><span style=\"font-weight: 400\">Vamos considerar a consulta e o \u00edndice a seguir:<\/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 default AS 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 necess\u00e1rio:<\/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\">A consulta tem GROUP BY e v\u00e1rios agregados, alguns dos agregados t\u00eam o modificador DISTINCT. O predicado da consulta tem a cl\u00e1usula ANY e a consulta pode ser coberta pelo \u00edndice de matriz idxad1. O 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 ) pode ser convertido em varreduras de intervalo exato e passado para a varredura de \u00edndice. Para o \u00edndice de matriz, o indexador mant\u00e9m um elemento separado para cada chave de \u00edndice de matriz. Para usar o grupo de \u00edndices e a agrega\u00e7\u00e3o, o predicado SATISFIES deve ter um \u00fanico predicado de igualdade e a chave de \u00edndice de matriz deve ter o modificador DISTINCT. Portanto, a combina\u00e7\u00e3o de \u00edndice e consulta \u00e9 adequada para lidar com o agrupamento e a agrega\u00e7\u00e3o 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 exemplo \u00e9 semelhante ao exemplo 1, exceto pelo fato de usar um \u00edndice de matriz. A \u00e1rvore de execu\u00e7\u00e3o gr\u00e1fica acima mostra a varredura de \u00edndice (IndexScan3) realizando varredura, agrega\u00e7\u00f5es de agrupamento de \u00edndice, ordem, deslocamento e limite. Os resultados da varredura de \u00edndice s\u00e3o projetados.<\/span><\/p>\n<h3><span style=\"font-weight: 400\">Exemplo 5: Grupo e agrega\u00e7\u00e3o da opera\u00e7\u00e3o UNNEST<\/span><\/h3>\n<p><span style=\"font-weight: 400\">Vamos considerar a consulta e o \u00edndice a seguir:<\/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) AS avgc1\r\nFROM default AS d UNNEST d.a1 AS v\r\nWHERE v.id &gt; 0\r\nGROUP BY v.id, d.c0;<\/pre>\n<p><span style=\"font-weight: 400\">\u00cdndice necess\u00e1rio:<\/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\">A consulta tem GROUP BY e v\u00e1rios agregados. A consulta tem UNNEST no array d.a1 e tem predicado na chave do array (v.id &gt; 0).  O \u00edndice idxaa1 qualifica a consulta (para que o Unnest use o \u00edndice da matriz para a varredura do \u00edndice, o \u00edndice da matriz deve ser a chave principal e a vari\u00e1vel da matriz na defini\u00e7\u00e3o do \u00edndice deve corresponder ao alias UNNEST). O predicado (v.id &gt; 0) pode ser convertido em varreduras de intervalo exato e passado para a varredura de \u00edndice.  Portanto, a combina\u00e7\u00e3o de \u00edndice e consulta \u00e9 adequada para lidar com agrupamentos e agrega\u00e7\u00f5es 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\">A \u00e1rvore de execu\u00e7\u00e3o gr\u00e1fica acima mostra a varredura de \u00edndice (IndexScan3) realizando varreduras e agrega\u00e7\u00f5es de agrupamento de \u00edndices. Os resultados da varredura de \u00edndice s\u00e3o projetados. O UNNEST \u00e9 um tipo especial de JOIN entre o pai e cada elemento da matriz. <\/span><span style=\"font-weight: 400\">Portanto, o UNNEST repete os campos do documento pai (d.c0, d.c1) e o <\/span><span style=\"font-weight: 400\">d.c0, dc.1<\/span><span style=\"font-weight: 400\"> refer\u00eancia teria duplicatas em compara\u00e7\u00e3o com o original <\/span><span style=\"font-weight: 400\">d<\/span><span style=\"font-weight: 400\"> documentos (\u00e9 necess\u00e1rio estar ciente disso ao usar SUM(), AVG()).<\/span><\/p>\n<h2><b>Regras para agrupamento e agrega\u00e7\u00e3o de \u00edndices<\/b><\/h2>\n<p><span style=\"font-weight: 400\"> \u00a0<\/span><span style=\"font-weight: 400\">\u00a0O agrupamento e a agrega\u00e7\u00e3o de \u00edndices s\u00e3o feitos por bloco de consulta, e a decis\u00e3o de usar ou n\u00e3o o agrupamento\/agrega\u00e7\u00e3o de \u00edndices \u00e9 tomada somente ap\u00f3s o processo de sele\u00e7\u00e3o de \u00edndices.<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">O bloco de consulta n\u00e3o deve conter Joins, NEST, SUBqueries.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">O bloco de consulta deve ser coberto por um \u00edndice de linha \u00fanica.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">O bloco de consulta n\u00e3o deve conter ARRAY_AGG()<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">O bloco de consulta n\u00e3o pode ser correlacionado<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Todos os predicados devem ser traduzidos exatamente em varreduras de intervalo.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">As express\u00f5es GROUP BY e Aggregate n\u00e3o podem fazer refer\u00eancia a nenhuma subconsulta, par\u00e2metro nomeado ou par\u00e2metro posicional.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Chaves GROUP BY, express\u00f5es agregadas podem ser chaves de \u00edndice, chave de documento, express\u00e3o em chaves de \u00edndice ou express\u00e3o em chave de documento<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">O \u00edndice precisa ser capaz de fazer o agrupamento e a agrega\u00e7\u00e3o em todos os agregados no bloco de consulta, caso contr\u00e1rio, n\u00e3o haver\u00e1 agrega\u00e7\u00e3o de \u00edndice. (ou seja, ALL ou None)<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">O agregado cont\u00e9m o modificador DISTINCT<\/span>\n<ul>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\"> As chaves de grupo devem corresponder exatamente \u00e0s chaves de \u00edndice principais (se a consulta contiver um predicado de igualdade na chave de \u00edndice, ela assumir\u00e1 que essa chave de \u00edndice est\u00e1 implicitamente inclu\u00edda nas chaves de GRUPO, se ainda n\u00e3o estiver presente). <\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">A express\u00e3o de agrega\u00e7\u00e3o deve estar em uma das n+1 chaves de \u00edndice principais (n representa o n\u00famero de chaves de grupo).<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\"> No caso do \u00edndice de parti\u00e7\u00e3o, as chaves de parti\u00e7\u00e3o devem corresponder exatamente \u00e0s chaves de grupo.<\/span><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h2><b>Resumo<\/b><\/h2>\n<p><span style=\"font-weight: 400\">Ao analisar o plano de explica\u00e7\u00e3o, correlacione os predicados na explica\u00e7\u00e3o com os intervalos e verifique se todos os predicados foram traduzidos exatamente para varreduras de intervalo e se a consulta est\u00e1 coberta. Certifique-se de que a consulta use agrupamentos e agrega\u00e7\u00f5es de \u00edndices e, se poss\u00edvel, que a consulta use agrega\u00e7\u00f5es completas do indexador ajustando as chaves do \u00edndice para melhorar o desempenho.<\/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 v26.1 (Yoast SEO v26.1.1) - 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\/pt\/understanding-index-grouping-aggregation-couchbase-n1ql-query\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\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\/pt\/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\":\"pt-BR\",\"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\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/understanding-index-grouping-aggregation-couchbase-n1ql-query\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@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\":\"pt-BR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@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\":\"pt-BR\",\"@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\/pt\/author\/sitaram-vemulapallicouchbase-com\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"SQL Group by Index | Aggregate Index SQL | Couchbase","description":"O agrupamento e as agrega\u00e7\u00f5es de \u00edndices podem melhorar a magnitude do desempenho da consulta e reduzir as lat\u00eancias para facilitar o processamento de consultas SQL para JSON.","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\/pt\/understanding-index-grouping-aggregation-couchbase-n1ql-query\/","og_locale":"pt_BR","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\/pt\/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":"pt-BR","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":"O agrupamento e as agrega\u00e7\u00f5es de \u00edndices podem melhorar a magnitude do desempenho da consulta e reduzir as lat\u00eancias para facilitar o processamento de consultas SQL para JSON.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/understanding-index-grouping-aggregation-couchbase-n1ql-query\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/understanding-index-grouping-aggregation-couchbase-n1ql-query\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@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":"Blog do Couchbase","description":"Couchbase, o banco de dados 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":"pt-BR"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"Blog do Couchbase","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"pt-BR","@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":"pt-BR","@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 \u00e9 engenheiro de software principal da Couchbase. Antes da Couchbase, ele atuou como arquiteto da IBM Informix SQL e tem mais de 20 anos de experi\u00eancia em design e desenvolvimento de bancos de dados. Sitaram tem mestrado em ci\u00eancia de sistemas e automa\u00e7\u00e3o pelo Indian Institute of Science, na \u00cdndia.","url":"https:\/\/www.couchbase.com\/blog\/pt\/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 \u00e9 engenheiro de software principal da Couchbase. Antes da Couchbase, ele atuou como arquiteto da IBM Informix SQL e tem mais de 20 anos de experi\u00eancia em design e desenvolvimento de bancos de dados. Sitaram tem mestrado em ci\u00eancia de sistemas e automa\u00e7\u00e3o pelo Indian Institute of Science, na \u00cdndia."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/4935","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/users\/7586"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/comments?post=4935"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/4935\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media\/4938"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media?parent=4935"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/categories?post=4935"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/tags?post=4935"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/ppma_author?post=4935"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}