Na MongoDB
documentação , é mencionado que:
Quando você precisa apenas de um subconjunto de campos de documentos, pode obter um melhor desempenho retornando apenas os campos necessários
Como os campos de filtragem afetam o desempenho? O desempenho está relacionado ao tamanho dos dados transmitidos pela rede? ou o tamanho dos dados que serão retidos na memória? Como exatamente esse desempenho é aprimorado? Qual é esse desempenho mencionado na documentação?
Tenho consultas lentas do MongoDB. O retorno de um subconjunto afeta minha consulta lenta (tenho índice composto no campo)?
mongodb
projection
ALH
fonte
fonte
Debian 8
,MongoDB 3.6.2
Respostas:
Por padrão, as consultas retornam todos os campos nos documentos correspondentes. Se você precisar de todos os campos, o retorno de documentos completos será mais eficiente do que o servidor manipular o conjunto de resultados com critérios de projeção.
No entanto, o uso da projeção para limitar os campos a serem retornados dos resultados da consulta pode melhorar o desempenho:
Ao usar a projeção para remover campos não utilizados, o servidor MongoDB precisará buscar cada documento completo na memória (se ainda não estiver lá) e filtrar os resultados para retornar. Esse uso da projeção não reduz o uso da memória ou o conjunto de trabalho no servidor MongoDB, mas pode economizar largura de banda de rede significativa para os resultados da consulta, dependendo do modelo de dados e dos campos projetados.
Uma consulta coberta é um caso especial em que todos os campos solicitados em um resultado da consulta são incluídos no índice usado, para que o servidor não precise buscar o documento completo. As consultas cobertas podem melhorar o desempenho (evitando a busca de documentos) e o uso de memória (se outras consultas não exigirem a busca do mesmo documento).
Exemplos
Para fins de demonstração via
mongo
shell, imagine que você tenha um documento parecido com este:O campo
b
pode representar uma seleção de valores (ou, nesse caso, uma sequência muito longa).Em seguida, crie um índice no
{a:1}
qual é um campo comumente usado pelo seu caso de uso:Um simples
findOne()
sem critério de projeção retorna um resultado de consulta de aproximadamente 10 MB:A adição da projeção
{a:1}
limitará a saída ao campoa
e ao documento_id
(que é incluído por padrão). O servidor MongoDB ainda está manipulando um documento de 10 MB para selecionar dois campos, mas o resultado da consulta agora é de apenas 33 bytes:Esta consulta não é coberta porque o documento completo precisa ser buscado para descobrir o
_id
valor. O_id
campo é incluído nos resultados da consulta por padrão, pois é o identificador exclusivo de um documento, mas_id
não será incluído em um índice secundário, a menos que seja explicitamente adicionado.As métricas
totalDocsExamined
etotalKeysExamined
nosexplain()
resultados mostrarão quantos documentos e chaves de índice foram examinados:Essa consulta pode ser aprimorada usando a projeção para excluir o
_id
campo e obter uma consulta coberta usando apenas o{a:1}
índice. A consulta coberta não precisa mais buscar um documento de ~ 10 MB na memória; portanto, será eficiente no uso da rede e da memória:Isso não pode ser respondido sem o contexto de uma consulta específica, um exemplo de documento e a saída completa da explicação. No entanto, você pode executar alguns benchmarks em seu próprio ambiente para a mesma consulta com e sem projeção para comparar o resultado. Se sua projeção está adicionando uma sobrecarga significativa ao tempo geral de execução da consulta (processamento e transferência de resultados), isso pode ser uma forte dica de que seu modelo de dados pode ser aprimorado.
Se não estiver claro por que uma consulta é lenta, seria melhor postar uma nova pergunta com detalhes específicos para investigar.
fonte
Com uma projeção, você pode alcançar uma situação em que o conjunto de resultados vem diretamente do índice.
Se você tiver um índice composto em
{x:1, y:1, z:1}
que nenhum de x, y, z é _id, será necessário projetar{_id:0, x:1, y:1, z:1}
porque_id
sempre é retornado como parte do conjunto de resultados (quando não é projetado para fora) e o mecanismo precisa ler os arquivos de dados para obtê-lo. Isso porque, o índice não tem o valor de _id, apenas o ponteiro para o documento em que o valor está armazenado.fonte
_id
da resposta retornada, isso cabe na RAM? Isso ajuda?_id:0
, o resultado será retornado totalmente da RAM, sem a leitura de dados do disco.