Partilhar via


Melhores Práticas de Indexação no Azure DocumentDB

Campos consultáveis devem sempre ter índices criados

As operações de leitura baseadas em predicados e agregados consultam o índice dos filtros correspondentes. Na ausência de índices, o motor da base de dados realiza uma análise de documentos para recuperar os documentos correspondentes. As digitalizações são sempre caras e tornam-se progressivamente mais caras à medida que o volume de dados numa coleção cresce. Para um desempenho ótimo na consulta, devem ser sempre criados índices para todos os campos consultáveis.

Evite índices desnecessários e a indexação de todos os campos por defeito

Os índices devem ser criados apenas para campos consultáveis. A indexação coringa deve ser usada apenas quando os padrões de consulta são imprevisíveis, onde qualquer campo na estrutura do documento pode fazer parte dos filtros de consulta.

Sugestão

O Azure DocumentDB apenas indexa o campo _id por defeito. Todos os outros campos não estão indexados por defeito. Os campos a indexar devem ser planeados antecipadamente para maximizar o desempenho da consulta, minimizando o impacto nas escritas devido à indexação de demasiados campos.

Quando um novo documento é inserido pela primeira vez ou um documento existente é atualizado ou eliminado, cada um dos campos especificados no índice também é atualizado. Se a política de indexação contiver um grande número de campos (ou todos os campos do documento), mais recursos são consumidos pelo servidor na atualização dos índices correspondentes. Ao correr em escala, apenas os campos consultáveis devem ser indexados, enquanto todos os campos restantes não usados nos predicados de consulta devem permanecer excluídos do índice.

Estratégia de indexação para uma ingestão eficiente de dados

Para migrações de cargas de trabalho grandes para o Azure DocumentDB, recomenda-se criar índices após a carga de dados para uma execução eficiente. Isto reduz significativamente a sobrecarga de escrita, minimiza o consumo de recursos e acelera o desempenho da ingestão de dados. Manter índices durante a ingestão em massa pode abrandar as inserções de dados, pois cada operação de escrita deve atualizar todos os índices aplicáveis.

Para múltiplos índices criados com dados históricos, emita comandos createIndex não bloqueantes para cada campo

Nem sempre é possível planear todos os padrões de consulta desde o início, especialmente à medida que os requisitos da aplicação evoluem. As necessidades de aplicação em mudança exigem inevitavelmente a adição de campos ao índice num cluster com uma grande quantidade de dados históricos.

Nesses cenários, cada comando createIndex deve ser emitido de forma assíncrona sem esperar resposta do servidor.

Observação

Por defeito, o Azure DocumentDB responde a uma operação createIndex apenas depois de o índice estar totalmente construído com base em dados históricos. Dependendo do tamanho do cluster e do volume de dados ingeridos, isto pode demorar tempo e parecer que o servidor não está a responder ao comando createIndex.

Se os comandos createIndex estiverem a ser emitidos através do Mongo Shell, use Ctrl + C para interromper o comando e deixar de esperar resposta e emitir o próximo conjunto de operações.

Observação

Usar Ctrl + C para interromper o comando createIndex após este ter sido emitido não termina a operação de construção do índice no servidor. Simplesmente impede que o Shell aguarde uma resposta do servidor, enquanto o servidor continua assíncronamente a construir o índice sobre os documentos existentes.

Crie Índices Compostos para consultas com predicados em múltiplos campos

Os índices compostos devem ser usados nos seguintes cenários:

  • Consultas com filtros em múltiplos campos
  • Consultas com filtros em múltiplos campos e com um ou mais campos ordenados por ordem crescente ou descendente

Considere o seguinte documento dentro da base de dados 'cosmicworks' e da coleção 'employee'

{
    "firstName": "Steve",
    "lastName": "Smith",
    "companyName": "Microsoft",
    "division": "Azure",
    "subDivision": "Data & AI",
    "timeInOrgInYears": 7
}

Considere a seguinte consulta para encontrar todos os colaboradores com o apelido 'Smith' na organização há mais de cinco anos:

db.employee.find({"lastName": "Smith", "timeInOrgInYears": {"$gt": 5}})

Um índice composto tanto em 'apelidoNome' como em 'timeInOrgInYears' otimiza esta consulta:

use cosmicworks;
db.employee.createIndex({"lastName" : 1, "timeInOrgInYears" : 1})

Acompanhar o estado de uma operação createIndex

Quando os índices são adicionados e os dados históricos precisam de ser indexados, o progresso da operação de construção do índice pode ser acompanhado usando db.currentOp().

Considere este exemplo para acompanhar o progresso da indexação na base de dados 'cosmicworks'.

use cosmicworks;
db.currentOp()

Quando uma operação createIndex está em curso, a resposta é a seguinte:

{
  "inprog": [
    {
      "shard": "defaultShard",
      "active": true,
      "type": "op",
      "opid": "30000451493:1719209762286363",
      "op_prefix": 30000451493,
      "currentOpTime": "2024-06-24T06:16:02.000Z",
      "secs_running": 0,
      "command": { "aggregate": "" },
      "op": "command",
      "waitingForLock": false
    },
    {
      "shard": "defaultShard",
      "active": true,
      "type": "op",
      "opid": "30000451876:1719209638351743",
      "op_prefix": 30000451876,
      "currentOpTime": "2024-06-24T06:13:58.000Z",
      "secs_running": 124,
      "command": { "createIndexes": "" },
      "op": "workerCommand",
      "waitingForLock": false,
      "progress": {},
      "msg": ""
    }
  ],
  "ok": 1
}

Ativar Chaves de Índice Grandes por defeito

Mesmo que os documentos não contenham chaves com um grande número de caracteres ou que os documentos não contenham múltiplos níveis de aninhamento, especificar chaves de índice grandes garante que estes cenários são cobertos. Agora, a grande chave de índice é o comportamento padrão do mecanismo.

Considere este exemplo para permitir chaves de índice grandes na coleção 'large_index_coll' da base de dados 'cosmicworks'.

use cosmicworks;
db.runCommand(
{
 "createIndexes": "large_index_coll",
 "indexes": [
    {
        "key": { "ikey": 1 },
        "name": "ikey_1",
        "enableLargeIndexKeys": true
    }
    ]
})

Priorizar a Construção de Índices em detrimento de novas Operações de Escrita usando a Opção de Bloqueio

Para cenários em que o índice deve ser criado antes de os dados serem carregados, a opção de bloqueio deve ser usada para bloquear escritas recebidas até à conclusão da construção do índice.

A configuração { "blocking": true } é útil em utilitários de migração, onde os índices são criados em coleções vazias antes do início das escritas dos dados.

Considere um exemplo da opção de bloqueio para criação de índice na coleção 'employee' na base de dados 'cosmicworks':

use cosmicworks;
db.runCommand({
  createIndexes: "employee",
  indexes: [{"key":{"name":1}, "name":"name_1"}],
  blocking: true
})

Experimente a indexação de texto, que permite uma pesquisa e consulta eficiente de dados baseados em texto.

Próximo passo