Otimização de Consulta
Nesta página
Os índices melhoram a eficiência das operações de leitura, reduzindo a quantidade de dados que as operações de query precisam processar. Isso simplifica o trabalho associado ao processamento de queries no MongoDB.
Crie um índice para dar suporte às operações de leitura
Se seu aplicação realizar uma query na collection sobre um determinado campo ou conjunto de campos, então um índice no campo da query ou umíndice composto no conjunto de campos pode impedir que a query verifique toda a collection para encontrar e retornar os resultados da query . Para obter mais informações sobre índices, consulte a documentação completa de índices no MongoDB.
Exemplo
Um aplicativo query a collection inventory
no campo type
. O valor do campo type
é orientado ao usuário.
var typeValue = <someUserInput>; db.inventory.find( { type: typeValue } );
Para melhorar o desempenho dessa query, adicione um índice crescente ou decrescente à coleção inventory
no campo type
. [1] No mongosh
, você pode criar índices utilizando o método db.collection.createIndex()
:
db.inventory.createIndex( { type: 1 } )
Esse índice pode impedir que a query acima em type
verifique toda a collection para retornar os resultados.
Para analisar o desempenho da query com um índice, consulte Analisar Desempenho da Consulta.
Além de otimizar operações de leitura, os índices podem oferecer suporte a operações de classificação e permitir uma utilização mais eficiente do armazenamento. Consulte db.collection.createIndex()
e Índices para mais informações sobre a criação de índices.
[1] | Para índices de campo único, a seleção entre ordem crescente e decrescente é irrelevante. Para índices compostos, a seleção é importante. Consulte a ordem de indexação para saber mais. |
Seletividade da query
A seletividade da query refere-se à eficiência com a qual o predicado da query exclui ou filtra documentos em uma collection. A seletividade da query pode determinar se as queries podem usar índices de forma eficaz ou não, ou sequer usá-los.
Queries mais seletivas correspondem a uma porcentagem menor de documentos. Por exemplo, uma correspondência de igualdade no campo _id
único é altamente seletiva, pois pode corresponder a no máximo um documento.
Queries menos seletivas fazem correspondência de uma percentagem maior de documentos. Queries menos seletivas não podem usar índices de forma eficaz, ou sequer usá-los.
Por exemplo, os operadores de desigualdade $nin
e $ne
não são muito seletivos, pois geralmente correspondem a uma grande parte do índice. Como resultado, em muitos casos, uma query $nin
ou $ne
com um índice pode ter um desempenho não melhor do que uma query $nin
ou $ne
, que deve digitalizar todos os documentos em uma collection.
A seletividade do regular expressions
depende das próprias expressões. Para detalhes, consulte expressão regular e uso de índice.
Query coberta
Uma query coberta é uma query que pode ser satisfeita inteiramente usando um índice e não precisa examinar nenhum documento. Um índice cobre uma query quando todas as opções a seguir se aplicam:
Todos os campos na query (tanto conforme especificado pelo aplicação quanto conforme necessário internamente, como para fins de fragmentação) fazem parte de um índice.
Todos os campos retornados nos resultados estão no mesmo índice.
Nenhum campo na query é igual a
null
. Por exemplo, os seguintes predicados de query não podem resultar em queries cobertas:{ "field": null }
{ "field": { $eq: null } }
Exemplo
Uma collection inventory
tem o seguinte índice nos campos type
e item
:
db.inventory.createIndex( { type: 1, item: 1 } )
O índice cobre a seguinte operação, que realiza a type
nos campos e item
item
o campo:
db.inventory.find( { type: "food", item:/^c/ }, { item: 1, _id: 0 } )
Para o índice especificado cobrir a query, o documento de projeção deve especificar explicitamente _id: 0
para excluir o campo _id
do resultado, já que o índice não inclui o campo _id
.
Documentos incorporados
Um índice pode cobrir uma query em campos dentro de documentos incorporados.
Por exemplo, considere uma collection userdata
com documentos da seguinte forma:
db.userdata.insertOne( { _id: 1, user: { login: "tester" } } )
A collection tem o seguinte índice:
db.userdata.createIndex( { "user.login": 1 } )
O índice { "user.login": 1 }
cobre a seguinte query:
db.userdata.find( { "user.login": "tester" }, { "user.login": 1, _id: 0 } )
Observação
Para indexar campos em documentos incorporados, use notação de ponto de ponto . Consulte Criar um índice em um campo incorporado.
Cobertura de múltiplas chaves
Os índices de múltiplas chaves podem cobrir queries sobre os campos que não são da array se o índice acompanhar qual(is) campo(s) faz(em) com que o índice seja de múltiplas chaves.
Os índices de múltiplas chaves não podem realizar query coberta no(s) campo(s) da array.
Para obter um exemplo de uma query coberta com um índice de múltiplas chaves, consulte Queries cobertas na página de índices de múltiplas chaves.
Desempenho
Como o índice contém todos os campos exigidos pela query, o MongoDB pode corresponder às condições da query e retornar os resultados usando apenas o índice.
Uma query apenas do índice pode ser muito mais rápido do que uma query de documentos fora do índice. As chaves de índice são normalmente menores do que os documentos que elas catalogam, e os índices geralmente estão disponíveis na RAM ou localizados sequencialmente no disco.
Limitações
Tipos de índice
Nem todos os tipos de índice podem cobrir queries. Para obter detalhes sobre o suporte a índices cobertos, consulte a página de documentação do tipo de índice correspondente.
Restrições à collection fragmentada
Ao executar no mongos
, os índices somente podem cobrir queries em collections fragmentadas se o índice contiver a chave de shard.
explain
Para determinar se uma query é uma query coberta, utilize o método db.collection.explain()
ou explain()
. Consulte queries cobertas.