Um índice composto faz referência a vários campos e pode melhorar drasticamente os tempos de resposta da query.
Na maioria dos casos, a aplicação da diretriz ESR (Equality, Sort, Range) para organizar as chaves do índice cria um índice compostomais eficiente.
Garanta que os campos de igualdade sempre estejam em primeiro lugar. A colocação dos campos de igualdade primeiro mantém os campos de índice restantes em uma ordem definida. Escolha se deseja usar um campo de classificação ou faixa em seguida com base nas necessidades específicas do seu índice:
Se evitar classificações na memória for fundamental, coloque os campos de classificação antes dos campos de intervalo (ESR)
Se o seu predicado de intervalo na query for muito seletivo, coloque-o antes dos campos de classificação (ERS)
Para saber mais sobre como otimizar queries, consulte explain e Planos de queries.
Dica
Para forçar o MongoDB a usar um índice específico, use cursor.hint() (método mongosh) ao testar índices.
Igualdade
"Igualdade" refere-se a uma correspondência exata em um único valor. As seguintes consultas de correspondência exata verificam a coleção cars em busca de documentos cujo campo model corresponda exatamente a Cordoba.
db.cars.find( { model: "Cordoba" } ) db.cars.find( { model: { $eq: "Cordoba" } } )
As pesquisas de índice fazem uso eficiente de correspondências exatas para reduzir o número de chaves de índice examinadas. Os campos de igualdade devem vir em primeiro lugar.
Um índice pode ter múltiplas chaves de igualdade. Elas podem aparecer em qualquer ordem relativa uma à outra, mas todas as chaves de igualdade devem preceder quaisquer campos de classificação ou faixa.
Quanto mais seletivas as correspondências de igualdade, mais eficiente é a query indexada.
Sort
"Classificar" determina a ordem dos resultados. Para evitar classificações na memória, coloque campos de classificação antes de faixas no índice.
Um índice suporta operações de classificação em um subconjunto de suas chaves somente quando a consulta inclui condições de igualdade em todas as chaves de prefixo que precedem as chaves de classificação. Para obter mais informações, consulte Classificação e Subconjunto sem Prefixo de um Índice.
O exemplo a seguir consulta a coleção cars. A saída é classificada por model:
db.cars.find( { manufacturer: "GM" } ).sort( { model: 1 } )
Para melhorar o desempenho da consulta, crie um índice nos campos manufacturer e model:
db.cars.createIndex( { manufacturer: 1, model: 1 } )
manufactureré a primeira chave porque é uma correspondência de igualdade.modelé indexado na mesma ordem (1) que a consulta.
faixa
Filtros de "faixa" verificam campos. A verificação não requer uma correspondência exata, o que significa que os filtros de faixa estão vagamente vinculados às chaves de índice. Para aumentar a eficiência da query, limite as faixas e use correspondências de igualdade para reduzir o número de documentos a serem verificados.
Filtros de faixa se assemelham ao seguinte:
db.cars.find( { price: { $gte: 15000} } ) db.cars.find( { age: { $lt: 10 } } ) db.cars.find( { priorAccidents: { $ne: null } } )
Se o predicado de intervalo em sua query for muito seletivo, coloque-o antes dos campos de classificação para reduzir o número de documentos classificados e permitir uma classificação na memória.
Para evitar uma classificação in-memory, coloque o filtro de faixa após o predicado de classificação. Para obter mais informações sobre classificações in-memory, consulte cursor.allowDiskUse().
Considerações adicionais
Operadores de desigualdade, como
$neou$ninsão operadores de alcance, não operadores de igualdade.$regexé um operador de alcance.Quando
$iné utilizado sozinho, é um operador de igualdade que executa uma série de correspondências de igualdade.Quando
$iné usado com.sort():Se
$intiver menos de 200 elementos de array, os elementos serão expandidos e mesclados na ordem de classificação especificada para o índice. Isso melhora o desempenho de arrays pequenas.$iné semelhante a um predicado de igualdade com ESR.Se
$intiver 200 elementos ou mais, os elementos serão ordenados como um operador de faixa. Nesse cenário, a melhoria de desempenho para arrays pequenas não é realizada. Não é possível que os campos subsequentes no índice forneçam uma classificação, e$iné semelhante a um predicado de faixa com ESR.Se você normalmente usa
$inscom arrays pequenas, inclua$insanteriormente na especificação do índice. Se você normalmente usa arrays grandes, inclua$insonde você incluiria um predicado de faixa.
Observação
O limite de 200 está sujeito a alterações e não é garantido que permaneça o mesmo em todas as versões do MongoDB.
Exemplo
A consulta a seguir pesquisa na coleção cars veículos fabricados pela Ford que custam mais de US$ 15.000. Os resultados são ordenados por modelo:
db.cars.find( { manufacturer: 'Ford', cost: { $gt: 15000 } } ).sort( { model: 1 } )
A query contém todos os elementos da Diretriz ESR:
manufacturer: 'Ford'é uma correspondência baseada em igualdadecost: { $gt: 15000 }é uma correspondência baseada em faixamodelé usado para classificar
Seguindo a diretriz ESR, o índice ideal para a query de exemplo é:
{ manufacturer: 1, model: 1, cost: 1 }