{"id":6792,"date":"2019-05-05T21:34:51","date_gmt":"2019-05-06T04:34:51","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=6792"},"modified":"2025-06-13T20:28:48","modified_gmt":"2025-06-14T03:28:48","slug":"query-optimization-in-nosql-couchbase-mongodb","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/pt\/query-optimization-in-nosql-couchbase-mongodb\/","title":{"rendered":"Abordagens para otimiza\u00e7\u00e3o de consultas em NoSQL"},"content":{"rendered":"<blockquote><p>Um homem voltou para casa depois de dar a volta ao mundo por onze anos.  No dia seguinte, quando ele disse \u00e0 esposa que estava indo para a loja da esquina, ela lhe perguntou: \"Voc\u00ea est\u00e1 fazendo o caminho mais curto ou o mais longo?\".<\/p><\/blockquote>\n<p>As consultas podem ser executadas de v\u00e1rias maneiras diferentes.  Todos os caminhos levam ao mesmo resultado de consulta.  A ferramenta NoSQL e de otimiza\u00e7\u00e3o de consultas avalia as possibilidades e seleciona o plano eficiente. A efici\u00eancia \u00e9 medida em lat\u00eancia e taxa de transfer\u00eancia, dependendo da carga de trabalho.  O custo da mem\u00f3ria, da CPU e do uso do disco \u00e9 adicionado ao custo de um plano em um otimizador baseado em custos.<\/p>\n<p>Agora, na maioria dos casos, um <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/resources\/why-nosql\/\">Banco de dados NoSQL<\/a> ter\u00e1 <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/unreasonable-effectiveness-of-sql\/\">Consulta do tipo SQL<\/a> suporte a idiomas. Portanto, um bom otimizador \u00e9 obrigat\u00f3rio. Quando n\u00e3o se tem um bom otimizador, os desenvolvedores t\u00eam de conviver com restri\u00e7\u00f5es de recursos e os DBAs t\u00eam de conviver com problemas de desempenho de consultas NoSQL.<\/p>\n<p><strong>Otimizador de banco de dados para melhorar as pesquisas de desempenho de NoSQL<\/strong><\/p>\n<p>A otimiza\u00e7\u00e3o de consultas NosSQL permite que voc\u00ea escolha um \u00edndice ideal e caminhos de acesso para executar a pesquisa. <span style=\"font-weight: 400\">Em um n\u00edvel muito alto, os otimizadores de SQL decidem o seguinte antes de criar a \u00e1rvore de execu\u00e7\u00e3o:<\/span><\/p>\n<ol>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Reescrita de consultas com base em heur\u00edstica, custo ou ambos.<\/span>\n<ul>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Assim como um editor remove palavras desnecess\u00e1rias de um texto, o trabalho de reescrita de consultas pode variar desde a elimina\u00e7\u00e3o de predicados desnecess\u00e1rios at\u00e9 o achatamento de subconsultas, convers\u00e3o de LEFT OUTER JOINS apropriados em INNER JOINS, dobra de tabelas derivadas etc.<\/span><\/li>\n<\/ul>\n<\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Sele\u00e7\u00e3o de \u00edndice.<\/span>\n<ul>\n<li style=\"font-weight: 400\">Selecionar o(s) \u00edndice(s) ideal(is) para cada tabela (espa\u00e7os-chave no Couchbase N1QL, cole\u00e7\u00e3o no caso das pr\u00e1ticas recomendadas de desempenho do MongoDB)<\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Dependendo do \u00edndice selecionado, escolha os predicados a serem enviados para baixo, veja se a consulta est\u00e1 coberta ou n\u00e3o, decida sobre a estrat\u00e9gia de classifica\u00e7\u00e3o e pagina\u00e7\u00e3o.<\/span><\/li>\n<\/ul>\n<\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Reordena\u00e7\u00e3o de jun\u00e7\u00f5es <\/span>\n<ul>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">(A INNER JOIN B INNER JOIN C) \u00e9 equivalente a (B INNER JOIN C INNER JOIN A).  O otimizador ter\u00e1 de determinar a melhor maneira de sequenciar essas uni\u00f5es.<\/span><\/li>\n<\/ul>\n<\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Tipo de uni\u00e3o<\/span>\n<ul>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Os bancos de dados podem implementar v\u00e1rios tipos de algoritmos de uni\u00e3o: loop aninhado, hash, mesclagem de classifica\u00e7\u00e3o, ziguezague, estrela (floco de neve) etc.  Dependendo da estrutura e do custo, o otimizador ter\u00e1 de decidir o tipo de algoritmo de uni\u00e3o para cada opera\u00e7\u00e3o de uni\u00e3o.<\/span><\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p>Considere o caso da restri\u00e7\u00e3o do MongoDB. <span style=\"font-weight: 400\">\"<\/span><span style=\"font-weight: 400\">Uma cole\u00e7\u00e3o pode ter no m\u00e1ximo <\/span><b>um<\/b> <span style=\"font-weight: 400\">texto<\/span><span style=\"font-weight: 400\"> \u00edndice\".\u00a0 <\/span><a href=\"https:\/\/docs.mongodb.com\/manual\/core\/index-text\/#restrictions\"><span style=\"font-weight: 400\">https:\/\/docs.mongodb.com\/manual\/core\/index-text\/#restrictions<\/span><\/a><span style=\"font-weight: 400\"> Al\u00e9m disso, ele documenta algumas outras restri\u00e7\u00f5es.  Para este artigo, ser\u00e1 suficiente explicar essa \u00fanica restri\u00e7\u00e3o.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-6794\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2019\/04\/Screen-Shot-2019-04-24-at-2.38.16-PM-300x65.png\" alt=\"\" width=\"733\" height=\"159\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/04\/Screen-Shot-2019-04-24-at-2.38.16-PM-300x65.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/04\/Screen-Shot-2019-04-24-at-2.38.16-PM-1024x223.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/04\/Screen-Shot-2019-04-24-at-2.38.16-PM-768x167.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/04\/Screen-Shot-2019-04-24-at-2.38.16-PM-1536x335.png 1536w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/04\/Screen-Shot-2019-04-24-at-2.38.16-PM-20x4.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/04\/Screen-Shot-2019-04-24-at-2.38.16-PM-1320x288.png 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/04\/Screen-Shot-2019-04-24-at-2.38.16-PM.png 1662w\" sizes=\"auto, (max-width: 733px) 100vw, 733px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p><strong>Por que voc\u00ea deve se preocupar com essa restri\u00e7\u00e3o?<\/strong><\/p>\n<ol>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">O MongoDB e outros bancos de dados NoSQL incentivam voc\u00ea a desnormalizar (agregar) seu esquema para criar um \u00fanico documento grande que represente um objeto: um cliente, um parceiro etc., de modo que a maioria das suas opera\u00e7\u00f5es ocorra em um \u00fanico documento (JSON).  Assim, um \u00fanico documento de cliente pode conter informa\u00e7\u00f5es do cliente, pedidos do cliente, informa\u00e7\u00f5es de remessa do cliente, informa\u00e7\u00f5es de faturamento do cliente. <\/span>Ter um \u00fanico \u00edndice de pesquisa significa que voc\u00ea precisa criar um \u00fanico \u00edndice MUITO GRANDE que combine todos os campos que voc\u00ea deseja pesquisar.  O problema \u00e9 o seguinte: quando voc\u00ea pesquisa o endere\u00e7o do cliente, n\u00e3o quer ver o endere\u00e7o de entrega. Quando voc\u00ea pesquisa o orderid de remessa, n\u00e3o quer ver o orderid retornado.<\/li>\n<li style=\"font-weight: 400\">Voc\u00ea pode criar v\u00e1rios \u00edndices em escalares no MongoDB.  Por que a restri\u00e7\u00e3o no \u00edndice de texto?<\/li>\n<\/ol>\n<p><strong>Por que o \u00edndice de texto do MongoDB \u00e9 restrito a um \u00edndice por cole\u00e7\u00e3o?\u00a0\u00a0<\/strong><\/p>\n<ul>\n<li style=\"list-style-type: none\">\n<ul>\n<li>\u00c9 o n\u00famero de \u00edndices de texto? Os \u00edndices de pesquisa geralmente s\u00e3o criados com um <a href=\"https:\/\/en.wikipedia.org\/wiki\/Inverted_index\">estrutura de dados de \u00e1rvore invertida<\/a>.  Mas, <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/searching-json-comparing-text-search-in-couchbase-and-mongodb\/\">O MongoDB optou por criar<\/a> com o \u00edndice B-Tree.  \u00c9 improv\u00e1vel que esse seja o problema.<\/li>\n<li>\u00c9 o tamanho dos \u00edndices de texto?  Os \u00edndices de texto geram uma matriz de tokens no texto e os indexam.  Portanto, \u00e9 um \u00edndice de matriz.  Seu tamanho pode crescer exponencialmente quando voc\u00ea usa um \u00edndice de matriz. O tamanho do \u00edndice aumenta linearmente com o n\u00famero de palavras indexadas e n\u00e3o com o n\u00famero de documentos.  Isso pode causar problemas.<\/li>\n<li>\u00c9 um problema com o otimizador?  Quando voc\u00ea tem v\u00e1rios \u00edndices, o otimizador ter\u00e1 que escolher o \u00edndice correto para a consulta.  Se voc\u00ea restringir a um \u00edndice de texto, a escolha ser\u00e1 f\u00e1cil. Esse \u00e9 um sintoma de um problema maior nas t\u00e9cnicas de otimiza\u00e7\u00e3o do MongoDB - ele toma decis\u00f5es adhoc que resultam em restri\u00e7\u00f5es como essa.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><span style=\"font-weight: 400\">A linguagem de plano de consulta do MongoDB \u00e9 simplista, mesmo que esteja tentando <\/span><a href=\"https:\/\/docs.mongodb.com\/manual\/reference\/sql-comparison\/\"><span style=\"font-weight: 400\">imitam as opera\u00e7\u00f5es do SQL.<\/span><\/a><span style=\"font-weight: 400\">.  Vamos ver como a ferramenta de otimiza\u00e7\u00e3o de consultas do MongoDB lida com isso.<\/span><\/p>\n<ol>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Reescrita de consulta: \u00a0<strong>Sem suporte<\/strong>. As consultas do MongoDB s\u00e3o simplistas nos m\u00e9todos find(), save(), remove(), update(). O pipeline de agrega\u00e7\u00e3o \u00e9 processual e detalhado. Embora seja teoricamente poss\u00edvel reescrever, n\u00e3o h\u00e1 nada na documenta\u00e7\u00e3o ou no plano que indique qualquer reescrita de consulta.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Sele\u00e7\u00e3o de \u00edndice: <strong>Com suporte<\/strong>.  O otimizador do MongoDB tenta escolher um \u00edndice adequado para cada parte da consulta e o \u00edndice pode\/deve ser usado. Mais sobre isso abaixo.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Reordena\u00e7\u00e3o de jun\u00e7\u00f5es: <strong>Sem suporte<\/strong>. O $lookup do MongoDB faz parte da estrutura de agrega\u00e7\u00e3o complicada em que a consulta \u00e9 escrita como um pipeline Unix, uma abordagem processual. \u00a0<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Sele\u00e7\u00e3o do tipo de uni\u00e3o: <strong>Sem suporte<\/strong> j\u00e1 que h\u00e1 apenas um tipo de jun\u00e7\u00e3o no MongoDB.  O MongoDB tem um suporte de jun\u00e7\u00e3o externa esquerda restrita por meio do operador $lookup - n\u00e3o h\u00e1 suporte para arrays na condi\u00e7\u00e3o de jun\u00e7\u00e3o.  Se voc\u00ea usar o $lookup, o otimizador usar\u00e1 automaticamente o algoritmo de jun\u00e7\u00e3o padr\u00e3o.  N\u00e3o h\u00e1 men\u00e7\u00e3o do tipo de uni\u00e3o feita.\u00a0\u00a0<\/span><\/li>\n<\/ol>\n<p><span style=\"font-weight: 400\">Essencialmente, a otimiza\u00e7\u00e3o de consultas do MongoDB s\u00f3 faz a sele\u00e7\u00e3o de \u00edndices antes de criar o plano de execu\u00e7\u00e3o. No entanto, a otimiza\u00e7\u00e3o de consultas no MongoDB parece selecionar os \u00edndices de forma estranha - nem por regra nem por estat\u00edstica. \u00a0<\/span><\/p>\n<ol>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Escolha um \u00edndice aleat\u00f3rio em um ou mais \u00edndices qualificados.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Use esse plano se uma consulta subsequente corresponder aos predicados da consulta, mesmo que as constantes, seletividades e cardinalidades sejam diferentes.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Em seguida, em tempo de execu\u00e7\u00e3o, se a varredura de \u00edndice retornar mais de 100 chaves (!), executa cada um dos planos alternativos para ver qual deles retorna as chaves primeiro.  Em algum momento, ele aborta a execu\u00e7\u00e3o paralela e escolhe um deles. Ele tamb\u00e9m substitui o plano em seu cache de planos.<\/span><\/li>\n<\/ol>\n<pre title=\"Defini\u00e7\u00e3o de \u00edndice do MongoDB\" class=\"theme:github font-size:15 scroll:true whitespace-before:1 whitespace-after:1 lang:default decode:true\">Collection t1, with 3000 documenbts.\r\n\r\nCreate the following indexes:  Appendix 1 for the definition:\r\n\r\nMongoDB Enterprise &gt; db.t1.createIndex({x:1})\r\nMongoDB Enterprise &gt; db.t1.createIndex({y:1})\r\nMongoDB Enterprise &gt; db.t1.createIndex({x:1, y:1})\r\nMongoDB Enterprise &gt; db.t1.createIndex({y:1, x:1})\r\n\r\n<\/pre>\n<p>Essa \u00e9 uma \u00fanica cole\u00e7\u00e3o com 4 \u00edndices em (x), (y), (x, y) e (y, x).  Agora, veja isso:<\/p>\n<pre class=\"theme:github font-size:15 wrap:true whitespace-before:1 whitespace-after:1 lang:js decode:true\">MongoDB Enterprise &gt; db.t1.find({x:{$gt:0}, y:99}).explain()\r\n{\r\n\t\"queryPlanner\" : {\r\n\t\t\"plannerVersion\" : 1,\r\n\t\t\"namespace\" : \"test.t1\",\r\n\t\t\"indexFilterSet\" : false,\r\n\t\t\"parsedQuery\" : {\r\n\t\t\t\"$and\" : [\r\n\t\t\t\t{\r\n\t\t\t\t\t\"y\" : {\r\n\t\t\t\t\t\t\"$eq\" : 99\r\n\t\t\t\t\t}\r\n\t\t\t\t},\r\n\t\t\t\t{\r\n\t\t\t\t\t\"x\" : {\r\n\t\t\t\t\t\t\"$gt\" : 0\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t]\r\n\t\t},\r\n\t\t\"winningPlan\" : {\r\n\t\t\t\"stage\" : \"FETCH\",\r\n\t\t\t\"filter\" : {\r\n\t\t\t\t\"x\" : {\r\n\t\t\t\t\t\"$gt\" : 0\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\t\"inputStage\" : {\r\n\t\t\t\t\"stage\" : \"IXSCAN\",\r\n\t\t\t\t\"keyPattern\" : {\r\n\t\t\t\t\t\"y\" : 1\r\n\t\t\t\t},\r\n\t\t\t\t\"indexName\" : \"y_1\",\r\n\t\t\t\t\"isMultiKey\" : false,\r\n\t\t\t\t\"multiKeyPaths\" : {\r\n\t\t\t\t\t\"y\" : [ ]\r\n\t\t\t\t},\r\n\t\t\t\t\"isUnique\" : false,\r\n\t\t\t\t\"isSparse\" : false,\r\n\t\t\t\t\"isPartial\" : false,\r\n\t\t\t\t\"indexVersion\" : 2,\r\n\t\t\t\t\"direction\" : \"forward\",\r\n\t\t\t\t\"indexBounds\" : {\r\n\t\t\t\t\t\"y\" : [\r\n\t\t\t\t\t\t\"[99.0, 99.0]\"\r\n\t\t\t\t\t]\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t},\r\n<\/pre>\n<p>Mesmo nessa estrutura simples de documento, o MongoDB seleciona o \u00edndice em (y), embora a consulta tenha filtros em x e y: <strong>({x:{$gt:0}, y:99})<\/strong>.<\/p>\n<p>Para gerenciar todas essas incertezas e os problemas de desempenho que elas acarretar\u00e3o, o MongoDB fornece um <a href=\"https:\/\/docs.mongodb.com\/manual\/reference\/method\/js-plan-cache\/\">n\u00famero de APIs para gerenciar o cache do plano de consulta<\/a>Se o usu\u00e1rio n\u00e3o tiver uma entrada de cache espec\u00edfica, ele poder\u00e1 liberar todo o cache do plano.   Em vez de desenvolver aplicativos, os desenvolvedores e DBAs do MongoDB precisam gerenciar o cache de planos.   Os desenvolvedores e DBAs n\u00e3o precisam gerenciar o cache de planos em outros bancos de dados corporativos.<\/p>\n<p>Voltemos \u00e0 pergunta original: <strong><em>Por que n\u00e3o \u00e9 poss\u00edvel criar v\u00e1rios \u00edndices de texto no MongoDB?<\/em><\/strong><\/p>\n<p>A cria\u00e7\u00e3o de v\u00e1rios \u00edndices n\u00e3o deveria ser um problema se eles simplesmente o permitissem.  A\u00a0<strong>problema real<\/strong> \u00e9 que, quando voc\u00ea fornece um predicado de texto em sua consulta, o otimizador do MongoDB n\u00e3o consegue escolher o \u00edndice correto.  Ele n\u00e3o pode validar esses \u00edndices de texto em rela\u00e7\u00e3o ao predicado de texto.  O otimizador do MongoDB n\u00e3o segue uma l\u00f3gica natural ou uma estrutura l\u00f3gica.   Da\u00ed a restri\u00e7\u00e3o.<\/p>\n<p><em>E isso pode at\u00e9 machuc\u00e1-lo!<\/em><\/p>\n<blockquote class=\"twitter-tweet\" data-lang=\"en\">\n<p dir=\"ltr\" lang=\"en\">Gosto muito de <a href=\"https:\/\/twitter.com\/hashtag\/MongoDB?src=hash&amp;ref_src=twsrc%5Etfw\">#MongoDB<\/a> mas escrever consultas em JSON \u00e9 doloroso (especialmente a agrega\u00e7\u00e3o). \u00c9 um inferno de par\u00eanteses curvos com suporte de ferramentas ruim. O mesmo vale para <a href=\"https:\/\/twitter.com\/hashtag\/ElasticSearch?src=hash&amp;ref_src=twsrc%5Etfw\">#ElasticSearch<\/a>. Felizmente, devido \u00e0s bibliotecas Java\/Kotlin, raramente temos que escrev\u00ea-las diretamente. Mas quando temos que faz\u00ea-lo, \u00e9 dif\u00edcil.<\/p>\n<p>- Philipp Hauer (@philipp_hauer) <a href=\"https:\/\/twitter.com\/philipp_hauer\/status\/1118804630635515905?ref_src=twsrc%5Etfw\">18 de abril de 2019<\/a><\/p><\/blockquote>\n<p>O Couchbase N1QL adicionou o \u00edndice de texto ao N1QL para a pr\u00f3xima vers\u00e3o.  Veja os detalhes em <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/n1ql-and-search-how-to-leverage-fts-index-in-n1ql-query\/\">https:\/\/www.couchbase.com\/blog\/n1ql-and-search-how-to-leverage-fts-index-in-n1ql-query\/<\/a>. Os usu\u00e1rios podem criar qualquer n\u00famero de \u00edndices de texto, e o otimizador escolher\u00e1 um \u00edndice qualificado (classific\u00e1vel) e o utilizar\u00e1.  Ele tamb\u00e9m \u00e9 compat\u00edvel com a pesquisa durante uni\u00f5es, varreduras p\u00f3s-\u00edndice, etc., porque o otimizador entende o predicado de pesquisa e as camadas em sua l\u00f3gica de decis\u00e3o.  N\u00e3o h\u00e1 nenhuma nova API ou novo plano para gerenciar. Esse \u00e9 o poder do Couchbase!<\/p>\n<h5 style=\"margin-bottom: 46.8359px\"><strong>Recursos:<\/strong><\/h5>\n<ol>\n<li>Uma vis\u00e3o geral da otimiza\u00e7\u00e3o de consultas em sistemas relacionais: <a href=\"https:\/\/web.stanford.edu\/class\/cs345d-01\/rl\/chaudhuri98.pdf\">https:\/\/web.stanford.edu\/class\/cs345d-01\/rl\/chaudhuri98.pdf<\/a><\/li>\n<li>Um mergulho profundo na otimiza\u00e7\u00e3o de consultas N1QL do Couchbase: <a href=\"https:\/\/dzone.com\/articles\/a-deep-dive-into-couchbase-n1ql-query-optimization\">https:\/\/dzone.com\/articles\/a-deep-dive-into-couchbase-n1ql-query-optimization<\/a><\/li>\n<li><a href=\"https:\/\/docs.mongodb.com\/manual\/reference\/method\/js-plan-cache\/\"><span style=\"font-weight: 400\">https:\/\/docs.mongodb.com\/manual\/reference\/method\/js-plan-cache\/<\/span><\/a><\/li>\n<li><a href=\"https:\/\/docs.mongodb.com\/manual\/core\/query-plans\/\"><span style=\"font-weight: 400\">https:\/\/docs.mongodb.com\/manual\/core\/query-plans\/<\/span><\/a><\/li>\n<li><a href=\"https:\/\/docs.mongodb.com\/manual\/reference\/method\/js-plan-cache\/\"><span style=\"font-weight: 400\">https:\/\/docs.mongodb.com\/manual\/reference\/method\/js-plan-cache\/<\/span><\/a><\/li>\n<\/ol>\n<p>&nbsp;<\/p>","protected":false},"excerpt":{"rendered":"<p>A man returned home after walking around the globe for eleven years.\u00a0 Next day, when he told his wife he&#8217;s going to the corner store, she asked him: &#8220;are you taking the short route or the long one?&#8221;. Queries can [&hellip;]<\/p>","protected":false},"author":55,"featured_media":4938,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1816,2165,1812],"tags":[1505,1261,1309,1725,1906],"ppma_author":[8929],"class_list":["post-6792","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-couchbase-server","category-full-text-search","category-n1ql-query","tag-index","tag-json","tag-mongodb","tag-nosql-database","tag-optimizer"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.7.1 (Yoast SEO v25.7) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Query Optimization in NoSQL and MongoDB Performance Plan<\/title>\n<meta name=\"description\" content=\"The NoSQL and query optimization tool evaluates the possibilities and selects the efficient plan. Find out what to do when you don\u2019t have a good optimizer.\" \/>\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\/query-optimization-in-nosql-couchbase-mongodb\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Approaches to Query Optimization in NoSQL\" \/>\n<meta property=\"og:description\" content=\"The NoSQL and query optimization tool evaluates the possibilities and selects the efficient plan. Find out what to do when you don\u2019t have a good optimizer.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/pt\/query-optimization-in-nosql-couchbase-mongodb\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2019-05-06T04:34:51+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T03:28:48+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=\"Keshav Murthy\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@rkeshavmurthy\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Keshav Murthy\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/query-optimization-in-nosql-couchbase-mongodb\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/query-optimization-in-nosql-couchbase-mongodb\/\"},\"author\":{\"name\":\"Keshav Murthy\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c261644262bf98e146372fe647682636\"},\"headline\":\"Approaches to Query Optimization in NoSQL\",\"datePublished\":\"2019-05-06T04:34:51+00:00\",\"dateModified\":\"2025-06-14T03:28:48+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/query-optimization-in-nosql-couchbase-mongodb\/\"},\"wordCount\":1365,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/query-optimization-in-nosql-couchbase-mongodb\/#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\":[\"Index\",\"JSON\",\"mongodb\",\"NoSQL Database\",\"Optimizer\"],\"articleSection\":[\"Couchbase Server\",\"Full-Text Search\",\"SQL++ \/ N1QL Query\"],\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/query-optimization-in-nosql-couchbase-mongodb\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/query-optimization-in-nosql-couchbase-mongodb\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/query-optimization-in-nosql-couchbase-mongodb\/\",\"name\":\"Query Optimization in NoSQL and MongoDB Performance Plan\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/query-optimization-in-nosql-couchbase-mongodb\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/query-optimization-in-nosql-couchbase-mongodb\/#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\":\"2019-05-06T04:34:51+00:00\",\"dateModified\":\"2025-06-14T03:28:48+00:00\",\"description\":\"The NoSQL and query optimization tool evaluates the possibilities and selects the efficient plan. Find out what to do when you don\u2019t have a good optimizer.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/query-optimization-in-nosql-couchbase-mongodb\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/query-optimization-in-nosql-couchbase-mongodb\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/query-optimization-in-nosql-couchbase-mongodb\/#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\/query-optimization-in-nosql-couchbase-mongodb\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Approaches to Query Optimization in NoSQL\"}]},{\"@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\/c261644262bf98e146372fe647682636\",\"name\":\"Keshav Murthy\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/4e51d72fc07c662aa791316deafffac4\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/af74df754db27152971d0aed2f323ead5a1f9fe5afd0209af91e12e784451224?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/af74df754db27152971d0aed2f323ead5a1f9fe5afd0209af91e12e784451224?s=96&d=mm&r=g\",\"caption\":\"Keshav Murthy\"},\"description\":\"Keshav Murthy is a Vice President at Couchbase R&amp;D. Previously, he was at MapR, IBM, Informix, Sybase, with more than 20 years of experience in database design &amp; development. He lead the SQL and NoSQL R&amp;D team at IBM Informix. He has received two President's Club awards at Couchbase, two Outstanding Technical Achievement Awards at IBM. Keshav has a bachelor's degree in Computer Science and Engineering from the University of Mysore, India, holds eleven US patents and has four US patents pending.\",\"sameAs\":[\"https:\/\/blog.planetnosql.com\/\",\"https:\/\/x.com\/rkeshavmurthy\"],\"url\":\"https:\/\/www.couchbase.com\/blog\/pt\/author\/keshav-murthy\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Query Optimization in NoSQL and MongoDB Performance Plan","description":"The NoSQL and query optimization tool evaluates the possibilities and selects the efficient plan. Find out what to do when you don\u2019t have a good optimizer.","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\/query-optimization-in-nosql-couchbase-mongodb\/","og_locale":"pt_BR","og_type":"article","og_title":"Approaches to Query Optimization in NoSQL","og_description":"The NoSQL and query optimization tool evaluates the possibilities and selects the efficient plan. Find out what to do when you don\u2019t have a good optimizer.","og_url":"https:\/\/www.couchbase.com\/blog\/pt\/query-optimization-in-nosql-couchbase-mongodb\/","og_site_name":"The Couchbase Blog","article_published_time":"2019-05-06T04:34:51+00:00","article_modified_time":"2025-06-14T03:28:48+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":"Keshav Murthy","twitter_card":"summary_large_image","twitter_creator":"@rkeshavmurthy","twitter_misc":{"Written by":"Keshav Murthy","Est. reading time":"7 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/query-optimization-in-nosql-couchbase-mongodb\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/query-optimization-in-nosql-couchbase-mongodb\/"},"author":{"name":"Keshav Murthy","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c261644262bf98e146372fe647682636"},"headline":"Approaches to Query Optimization in NoSQL","datePublished":"2019-05-06T04:34:51+00:00","dateModified":"2025-06-14T03:28:48+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/query-optimization-in-nosql-couchbase-mongodb\/"},"wordCount":1365,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/query-optimization-in-nosql-couchbase-mongodb\/#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":["Index","JSON","mongodb","NoSQL Database","Optimizer"],"articleSection":["Couchbase Server","Full-Text Search","SQL++ \/ N1QL Query"],"inLanguage":"pt-BR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/query-optimization-in-nosql-couchbase-mongodb\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/query-optimization-in-nosql-couchbase-mongodb\/","url":"https:\/\/www.couchbase.com\/blog\/query-optimization-in-nosql-couchbase-mongodb\/","name":"Query Optimization in NoSQL and MongoDB Performance Plan","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/query-optimization-in-nosql-couchbase-mongodb\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/query-optimization-in-nosql-couchbase-mongodb\/#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":"2019-05-06T04:34:51+00:00","dateModified":"2025-06-14T03:28:48+00:00","description":"The NoSQL and query optimization tool evaluates the possibilities and selects the efficient plan. Find out what to do when you don\u2019t have a good optimizer.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/query-optimization-in-nosql-couchbase-mongodb\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/query-optimization-in-nosql-couchbase-mongodb\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/query-optimization-in-nosql-couchbase-mongodb\/#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\/query-optimization-in-nosql-couchbase-mongodb\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Approaches to Query Optimization in NoSQL"}]},{"@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\/c261644262bf98e146372fe647682636","name":"Keshav Murthy","image":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/4e51d72fc07c662aa791316deafffac4","url":"https:\/\/secure.gravatar.com\/avatar\/af74df754db27152971d0aed2f323ead5a1f9fe5afd0209af91e12e784451224?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/af74df754db27152971d0aed2f323ead5a1f9fe5afd0209af91e12e784451224?s=96&d=mm&r=g","caption":"Keshav Murthy"},"description":"Keshav Murthy \u00e9 vice-presidente de P&amp;D da Couchbase. Anteriormente, ele trabalhou na MapR, IBM, Informix e Sybase, com mais de 20 anos de experi\u00eancia em design e desenvolvimento de bancos de dados. Ele liderou a equipe de P&amp;D de SQL e NoSQL na IBM Informix. Ele recebeu dois pr\u00eamios President's Club na Couchbase e dois Outstanding Technical Achievement Awards na IBM. Keshav \u00e9 bacharel em Ci\u00eancia da Computa\u00e7\u00e3o e Engenharia pela Universidade de Mysore, \u00cdndia, det\u00e9m onze patentes nos EUA e tem quatro patentes pendentes nos EUA.","sameAs":["https:\/\/blog.planetnosql.com\/","https:\/\/x.com\/rkeshavmurthy"],"url":"https:\/\/www.couchbase.com\/blog\/pt\/author\/keshav-murthy\/"}]}},"authors":[{"term_id":8929,"user_id":55,"is_guest":0,"slug":"keshav-murthy","display_name":"Keshav Murthy","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/af74df754db27152971d0aed2f323ead5a1f9fe5afd0209af91e12e784451224?s=96&d=mm&r=g","first_name":"Keshav","last_name":"Murthy","user_url":"https:\/\/blog.planetnosql.com\/","author_category":"","description":"Keshav Murthy \u00e9 vice-presidente de P&amp;D da Couchbase. Anteriormente, ele trabalhou na MapR, IBM, Informix e Sybase, com mais de 20 anos de experi\u00eancia em design e desenvolvimento de bancos de dados. Ele liderou a equipe de P&amp;D de SQL e NoSQL na IBM Informix. Recebeu dois pr\u00eamios President's Club na Couchbase e dois Outstanding Technical Achievement Awards na IBM. Keshav \u00e9 bacharel em Ci\u00eancia da Computa\u00e7\u00e3o e Engenharia pela Universidade de Mysore, \u00cdndia, det\u00e9m dez patentes nos EUA e tem tr\u00eas patentes pendentes nos EUA."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/6792","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\/55"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/comments?post=6792"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/6792\/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=6792"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/categories?post=6792"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/tags?post=6792"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/ppma_author?post=6792"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}