Crie índices eficientes no ApsaraDB for MongoDB analisando a eficiência dos índices, escolhendo o tipo adequado e otimizando-os para consultas específicas.
Como escolha um índice
O ApsaraDB for MongoDB oferece suporte a vários tipos de índices. Selecione o tipo de índice de acordo com o seu cenário.
-
Use índices de chave única
Se todas as suas consultas utilizam uma única chave, crie um índice de chave única.
-
Use compound indexes
Se suas consultas utilizam condições de chave única e de múltiplas chaves, crie um compound index com suporte a até 32 chaves. O exemplo a seguir crie um compound index nos campos category e item.
db.products.createIndex( { "category": 1, "item": 1 } ) -
Use índices de texto
Um índice convencional faz a correspondência pelo valor exato de um campo. Para localizar palavras específicas em um campo de texto extenso, use um índice de texto. Para mais informações, consulte Text Indexes on Self-Managed Deployments.
Especifique collations de índice
Para usar índices em comparações de strings, especifique a mesma collation tanto na operação de criação do índice quanto na consulta. Índices com uma collation definida não suportam consultas que utilizem uma collation diferente.
O exemplo a seguir apresenta uma coleção com um índice no campo de string myColl. O índice usa a collation locale category "fr":
db.myColl.createIndex( { category: 1 }, { collation: { locale: "fr" } } )
Especifique a mesma collation do índice para utilizá-lo na seguinte operação de consulta:
db.myColl.find( { category: "cafe" } ).collation( { locale: "fr" } )
A operação de consulta a seguir usa a collation binária padrão "simple" e não consegue utilizar o índice:
db.myColl.find( { category: "cafe" } )
Para compound indexes cujas chaves de prefixo não sejam string, array ou documento embutido, operações de consulta com uma collation diferente ainda podem usar o índice para comparações dessas chaves de prefixo. Para mais informações sobre collations, consulte Collation Locales and Default Parameters.
Analise índices com base em logs de consulta lenta
O ApsaraDB for MongoDB otimiza índices para reduzir o número de coleções varridas. Monitore as métricas DocsExamined e KeysExamined nos logs de consulta lenta. Para mais informações sobre como visualize logs de consulta lenta, consulte Ver logs de consulta lenta.
DocsExamined: número de documentos varridos em uma consulta. Um valor alto indica que muitas entradas sem índice estão sendo varridas. Crie um índice nos campos consultados para reduzir esse número.
KeysExamined: número de chaves de índice varridas. Se esse valor for alto mas nreturned for baixo, o índice é ineficiente. Ajuste o índice existente ou crie um mais seletivo.
A lógica de análise de índices a seguir se aplica:
-
Varredura completa de coleção (palavras-chave: COLLSCAN e DocsExamined)
COLLSCAN indica uma varredura completa de coleção. Se essa palavra-chave aparecer nos logs de consulta lenta após uma operação de consulta, atualização ou exclusão, crie índices nos campos consultados.
DocsExamined indica o número de documentos varridos em uma consulta. Quanto maior o valor, mais recursos de CPU são consumidos.
-
Índices inadequados (palavras-chave: IXSCAN e keysExamined)
keysExamined indica o número de chaves de índice varridas. Quanto maior o valor, mais recursos de CPU são consumidos.
Um índice inadequado, ou que corresponde a um volume excessivo de dados, não reduz o overhead de CPU nem acelera as consultas.
Ao encontrar a palavra-chave SORT nos logs de consulta lenta, use um índice para otimizar o desempenho de ordenação. Para mais informações, consulte The ESR (Equality, Sort, Range) Rule.
Como otimizar índices
Use covered queries
Uma covered query retorna resultados diretamente do índice, sem acessar o documento source. Para determinar se uma consulta é uma covered query, use o comando explain(). Se a saída de explain() mostrar que totalDocsExamined é 0, a consulta está coberta pelo índice.
Se a saída de explain() não contiver o campo totalDocsExamined, execute a consulta no modo executionStats ou allPlansExecution. Por exemplo, use explain("executionStats") ou explain("allPlansExecution").
Ao implementar uma covered query, o campo _id é retornado por padrão. Exclua-o explicitamente dos resultados da consulta ou adicione-o ao índice.
Em um sharded cluster, o MongoDB precisa acessar internamente os campos da sharding key. Para que uma consulta seja coberta, a sharding key deve fazer parte do índice. Portanto, a melhor prática é incluir a sharding key nos seus índices.
Remova índices redundantes
Índices consomem RAM e recursos de disco, mesmo com a compressão do WiredTiger. Atualize campos indexados também gera overhead de CPU e de I/O em disco. Avalie criteriosamente e remova os índices que não são mais necessários.
Recomendações para compound indexes
Em uma consulta composta sobre múltiplos campos, a ordem dos campos na consulta não importa — basta um único índice. Por exemplo, para uma consulta nos campos
aeb, é suficiente ter um dos índices{a:1, b:1}ou{b:1, a:1}.-
Índices redundantes podem surgir de relações de inclusão entre consultas. Considere os seguintes exemplos:
db.myCol.find({"b": 2, "c": 3})db.myCol.find({"a": 1, "b": 2, "c": 3})
A segunda consulta abrange todos os campos da primeira. Um único índice é suficiente para atender às duas consultas. Para isso, posicione os campos da consulta mais específica no início do índice. O índice deve ser
{b: 1, c: 1, a: 1}. -
Índices redundantes podem ocorrer pela combinação de um índice único com outros campos. Considere os seguintes exemplos:
db.myCol.find({"a": 1, "b": 1})db.myCol.find({"a": 1, "c": 1})
Se o campo
apossui valores únicos, criar um compound index com outros campos além deanão traz benefício para essas consultas. Basta criar um índice em{a: 1}.
Recomendações para índices de consultas não equivalentes
-
Evite criar um índice composto de consulta não equivalente para determinadas consultas. Exemplo:
db.myCol.find({"a": {$gte: 1} , "b": {$lte: 1}})Nessa consulta não equivalente com múltiplos campos, apenas o campo mais à esquerda pode ser indexado. Basta criar um índice no campo a.
-
É possível combinar consultas equivalentes e não equivalentes. Exemplo:
db.myCol.find({"a": {$gte: 1} , "b": 1})Nesse caso, o índice ideal deve ter o campo de consulta de igualdade em primeiro lugar. Crie o índice
{b: 1, a: 1}.
Recomendações para índices de consultas do tipo $or
Consultas do tipo $or exigem a criação de um índice para cada condição. Exemplo:
db.myCol.find({$or: [{"a": 1, "b": 1}, {"c": 1, "d": 1}]})
Crie um índice ideal para cada cláusula da consulta $or. Para a consulta {$or: [{"a": 1, "b": 1}, {"c": 1, "d": 1}]}, crie dois índices separados, {a: 1, b: 1} e {c: 1, d: 1}, em vez de um único compound index como {a: 1, b: 1, c: 1, d: 1}.
Recomendações para índices de consultas com ordenação
-
Para consultas de ordenação diferentes que contenham o mesmo campo, basta criar um único índice. Exemplo:
db.myCol.find({}).sort({"a":1})db.myCol.find({}).sort({"a":-1})
Basta criar o índice
{a: 1}. -
Também é possível usar consultas de ordenação com múltiplos campos. Exemplo:
db.myCol.find({}).sort({"a":1, "b": -1})O índice
{a: 1, b: 1}não é eficaz para essa consulta. Crie o índice{a: 1, b: -1}. -
Outra opção é combinar consultas equivalentes, não equivalentes e de ordenação. Exemplo:
db.myCol.find({"a": 1, "b": 2, "c": {$gte: 1}}).sort({"d": 1, "e": -1})A ordem dos campos em um índice deve seguir a sequência
equality->sort->non-equality. Nesse exemplo, o índice correto é{a: 1, b: 1, d: 1, e: -1, c: 1}. -
Também é possível combinar consultas do tipo $or com ordenação. Exemplo:
db.myCol.find({$or: [{"a": 1, "b": 1}, {"c": 1, "d": 1}]}).sort({"e": -1})Essa consulta pode ser dividida em duas:
db.myCol.find({"a": 1, "b": 1}).sort({"e":-1})edb.myCol.find({"c": 1, "d": 1}).sort({"e":-1}). Seguindo a regra de combinação entre igualdade e ordenação, crie os índices{a: 1, b: 1, e: -1}e{c: 1, d: 1, e: -1}.
Use uma projeção para retornar apenas os campos necessários
Para retornar apenas campos específicos de um documento, use uma projeção para melhor desempenho.
Por exemplo, para recuperar apenas os campos timestamp, title, author e abstract da coleção posts, execute a seguinte consulta:
db.posts.find( {}, { timestamp : 1 , title : 1 , author : 1 , abstract : 1} ).sort( { timestamp : -1 } )
Use hint() para selecione um índice específico
Na maioria dos casos, o otimizador de consultas selecione o índice ideal automaticamente. No entanto, use o método hint() para forçar o MongoDB a utilizar um índice específico.
Por exemplo, use hint() em testes de desempenho ou em consultas nas quais seja necessário selecione um campo presente em múltiplos índices.
Use índices parciais
Índices parciais reduzem o tamanho e o overhead de desempenho dos índices ao indexar apenas os documentos que correspondem a uma expressão de filtro.
Por exemplo, considere uma coleção com os campos a, b, c. Se suas condições de consulta incluem apenas o campo a, crie um índice somente no campo a.