Compartilhar via


Políticas de indexação no Azure Cosmos DB

APLICA-SE A: NoSQL

No Azure Cosmos DB, cada contêiner tem uma política de indexação que determina como os itens do contêiner devem ser indexados. A política de indexação padrão para contêineres recém-criados indexa cada propriedade de cada item e impõe índices de intervalo para qualquer cadeia de caracteres ou número. Isso permite que você obtenha um bom desempenho de consulta sem precisar pensar na indexação e no gerenciamento de índice antecipadamente.

Em algumas situações, talvez você queira substituir esse comportamento automático para atender melhor às suas necessidades. Você pode personalizar a política de indexação de um contêiner configurando o modo de indexação e incluindo ou excluindo os caminhos de propriedade.

Observação

O método de atualização das políticas de indexação descritos neste artigo se aplica somente à API do Azure Cosmos DB para NoSQL. Saiba mais sobre a indexação em API do Azure Cosmos DB para MongoDB

Modo de indexação

O Azure Cosmos DB dá suporte a dois modos de indexação:

  • Consistente: o índice é atualizado de maneira síncrona à medida que você cria, atualiza ou exclui itens. Isso significa que a consistência das suas consultas de leitura será a consistência configurada da conta.
  • Nenhum: a indexação está desabilitada no contêiner. Esse modo normalmente é usada quando um contêiner funciona como um repositório de chave-valor puro sem a necessidade de índices secundários. Ela também pode ser usada para aprimorar o desempenho de operações em massa. Depois que as operações em massa forem concluídas, o modo de índice poderá ser definido como Consistente e monitorado usando o IndexTransformationProgress até a conclusão.

Observação

O Azure Cosmos DB também dá suporte a um modo de Indexação lenta. A indexação lenta faz atualizações no índice em um nível de prioridade muito menor quando o mecanismo não executa outros trabalhos. Isso pode resultar em resultados de consultas inconsistentes ou incompletas. Se você planeja consultar um contêiner do Azure Cosmos DB, não selecione a indexação lenta. Os novos contêineres não podem selecionar a indexação lenta. Você pode solicitar uma isenção entrando em contato com o cosmosdbindexing@microsoft.com (a não ser que você esteja usando uma conta do Azure Cosmos DB no modo sem servidor que não dá suporte à indexação lenta).

Por padrão, a política de indexação está definida como automatic. Ela é obtida configurando a propriedade automatic na política de indexação como true. Configurar essa propriedade como true permite que o Azure Cosmos DB indexe automaticamente os documentos conforme eles são gravados.

Tamanho do índice

No Azure Cosmos DB, o armazenamento consumido total é a combinação do Tamanho dos dados e do Tamanho do índice. Veja abaixo alguns recursos de tamanho do índice:

  • O tamanho do índice depende da política de indexação. Se todas as propriedades forem indexadas, o tamanho do índice poderá ser maior do que o tamanho dos dados.
  • Quando os dados forem excluídos, os índices serão compactados quase continuamente. No entanto, em exclusões de dados pequenas, talvez você não observe imediatamente uma diminuição no tamanho do índice.
  • O tamanho do Índice poderá aumentar temporariamente quando as partições físicas forem divididas. O espaço do índice é lançado após a conclusão da divisão da partição.

Inclusão e exclusão dos caminhos de propriedade

Uma política de indexação personalizada pode especificar caminhos de propriedade que são explicitamente incluídos ou excluídos da indexação. Ao otimizar o número de caminhos que são indexados, você pode reduzir substancialmente a latência e preço da RU das operações de gravação. Esses caminhos são definidos seguindo o método descrito na seção visão geral da indexação com as seguintes adições:

  • um caminho que leva a um valor escalar (cadeia de caracteres ou número) termina com /?
  • os elementos de uma matriz são administrados em conjunto por meio da notação /[] (em vez de /0, /1 etc.)
  • o curinga /* pode ser usado para corresponder qualquer elemento abaixo do nó

Usando o mesmo exemplo novamente:

    {
        "locations": [
            { "country": "Germany", "city": "Berlin" },
            { "country": "France", "city": "Paris" }
        ],
        "headquarters": { "country": "Belgium", "employees": 250 },
        "exports": [
            { "city": "Moscow" },
            { "city": "Athens" }
        ]
    }
  • o caminho employees do headquarters é /headquarters/employees/?

  • o caminho country do locations é /locations/[]/country/?

  • o caminho para tudo em headquarters é /headquarters/*

Por exemplo, poderíamos incluir o caminho /headquarters/employees/?. Esse caminho garantiria a indexação da propriedade employees, mas não indexaria o JSON aninhado extra dentro dessa propriedade.

Estratégia de inclusão/exclusão

Qualquer política de indexação deve incluir o caminho raiz /* como um caminho incluído ou excluído.

  • Inclua o caminho raiz para excluir seletivamente os caminhos que não precisam ser indexados. Essa abordagem é recomendada, pois permite que Azure Cosmos DB indexe proativamente todas as novas propriedades que forem adicionadas ao seu modelo.

  • Exclua o caminho raiz para incluir seletivamente os caminhos que precisam ser indexados. O caminho da propriedade da chave de partição não é indexado por padrão com a estratégia de exclusão e deve ser incluído explicitamente, se necessário.

  • Em caminhos com caracteres regulares que incluem caracteres alfanuméricos e _ (sublinhado), você não precisa escapar a cadeia de caracteres do caminho com aspas duplas (por exemplo, "/path/?"). Em caminhos com outros caracteres especiais, você precisa escapar a cadeia de caracteres do caminho com aspas duplas (por exemplo, "/"path-abc"/?"). Se você acredita que terá caracteres especiais no seu caminho, pode escapar todos os caminhos por precaução. Funcionalmente, não faz diferença se você escapar todos os caminhos ou apenas aqueles que têm caracteres especiais.

  • A propriedade do sistema _etag é excluída da indexação por padrão, a menos que a etag seja adicionada ao caminho incluído para indexação.

  • Se o modo de indexação estiver definido como consistente, as propriedades do sistema id e _ts serão indexadas automaticamente.

  • Se um caminho explicitamente indexado não existir em um item, um valor é adicionado ao índice para indicar que o caminho é indefinido.

Todos os caminhos explicitamente incluídos terão valores adicionados ao índice para cada item no contêiner, mesmo que o caminho seja indefinido para um determinado item.

Confira esta seção para obter exemplos de política de indexação para incluir e excluir caminhos.

Precedência de inclusão/exclusão

Se os caminhos incluídos e os caminhos excluídos tiverem um conflito, o caminho mais preciso terá precedência.

Veja um exemplo:

Caminho incluído: /food/ingredients/nutrition/*

Caminho excluído: /food/ingredients/*

Nesse caso, o caminho incluído tem precedência sobre o caminho excluído porque ele é mais preciso. Com base nesses caminhos, todos os dados no caminho food/ingredients ou aninhados nele serão excluídos do índice. Os dados no caminho incluído /food/ingredients/nutrition/* são a exceção, pois eles seriam indexados.

Veja abaixo algumas regras para precedência de caminhos incluídos e excluídos no Azure Cosmos DB:

  • Caminhos mais profundos são mais precisos do que caminhos mais estreitos. por exemplo: /a/b/? é mais preciso do que /a/?.

  • /? é mais preciso do que /*. Por exemplo, /a/? é mais preciso do que /a/*, portanto /a/? tem precedência.

  • O caminho /* precisa ser um caminho incluído ou um caminho excluído.

Índices de texto completo

Observação

Você deve habilitar a versão prévia do recurso Texto Completo e Pesquisa Híbrida para a API do NoSQL para especificar um índice de texto completo.

Os índices de texto completo habilitam a pesquisa de texto completo e a pontuação com eficiência usando o índice. Definir um caminho de texto completo em uma política de indexação pode ser feito facilmente incluindo uma seção fullTextIndexes da política de indexação que contém todos os caminhos de texto a serem indexados. Por exemplo:

{
    "indexingMode": "consistent",
    "automatic": true,
    "includedPaths": [
        {
            "path": "/*"
        }
    ],
    "excludedPaths": [
        {
            "path": "/\"_etag\"/?"
        },
    ],
    "fullTextIndexes": [
        {
            "path": "/text"
        }
    ]
}

Importante

Uma política de indexação de texto completo deve estar no caminho definido na política de texto completo do contêiner. Saiba mais sobre as políticas de vetor de contêiner.

Índices de vetor

Observação

Você deve habilitar o recurso Busca em Vetores no Azure Cosmos DB for NoSQL para especificar um índice de vetor.

Os índices de vetor aumentam a eficiência ao realizar buscas em vetores usando a função do sistema VectorDistance. As buscas em vetores têm menor latência, maior taxa de transferência e menor consumo de Unidade de Solicitação (RU) ao aplicar um índice de vetores. Você pode especificar os seguintes tipos de políticas de índice de vetores:

Tipo Descrição Dimensões máximas
flat Armazena vetores no mesmo índice que outras propriedades indexadas. 505
quantizedFlat Quantifica (compacta) vetores antes de armazenar no índice. Isto pode melhorar a latência e a taxa de transferência ao custo de uma pequena quantidade de precisão. 4096
diskANN Cria um índice baseado em DiskANN para uma pesquisa aproximada rápida e eficiente. 4096

Importante

Atualmente, as políticas de vetor e os índices de vetor são imutáveis após a criação. Para fazer alterações, crie uma nova coleção.

Alguns pontos a serem observados:

  • Os tipos de índice flat e quantizedFlat aplicam o índice do Azure Cosmos DB para armazenar e acessar cada vetor durante uma busca em vetores. Buscas em vetores com um índice flat são buscas de força bruta e garantem 100% de exatidão ou recall. Ou seja, é garantido encontrar os vetores mais similares no conjunto de dados. Contudo, há uma limitação de 505 dimensões para vetores em um índice plano.

    • O índice quantizedFlat armazena vetores compartimentalizados (comprimidos) no índice. Buscas em vetores com índice quantizedFlat também são buscas de força bruta, contudo, a exatidão pode ser um pouco menor que 100%, já que os vetores são compartimentalizados antes de serem adicionados ao índice. No entanto, buscas em vetores com quantized flat devem ter menor latência, maior taxa de transferência e menor custo de RU do que buscas em vetores em um índice flat. Essa é uma boa opção para cenários em que você está usando filtros de consulta para restringir a busca em vetores a um conjunto relativamente pequeno de vetores e precisa de uma precisão bastante elevada.

    • O índice diskANN é separado e definido especificamente para vetores que aplicam DiskANN, uma série de algoritmos de indexação de vetores de alta desempenho desenvolvidos pela Microsoft Research. Os índices DiskANN podem oferecer algumas das consultas de menor latência, maior taxa de transferência e menor custo de RU, mantendo ainda uma alta exatidão. No entanto, como o DiskANN é um índice de vizinho mais próximo (ANN), a exatidão pode ser menor que quantizedFlat ou flat.

Os índices diskANN e os índices quantizedFlat podem usar parâmetros opcionais de build de índice que podem ser usados para ajustar a precisão versus a compensação de latência que se aplica a cada índice de vetor aproximado de vizinhos mais próximos.

  • quantizationByteSize: define o tamanho (em bytes) para a quantização do produto. Min=1, Default=dynamic (system decides), Max=512. Definir esse valor maior pode resultar em busca em vetores de maior precisão em detrimento de maior custo de RU e latência mais alta. Isso se aplica aos tipos de índice quantizedFlat e DiskANN.
    • indexingSearchListSize: define quantos vetores pesquisar durante a construção da compilação do índice. Min=10, Default=100, Max=500. Definir esse valor maior pode resultar em busca em vetores de maior precisão em detrimento de tempos de build de índice mais longos e latências de ingestão de vetor mais altas. Isso se aplica somente a DiskANN índices.

Aqui está um exemplo de uma política de indexação com um índice de vetor:

{
    "indexingMode": "consistent",
    "automatic": true,
    "includedPaths": [
        {
            "path": "/*"
        }
    ],
    "excludedPaths": [
        {
            "path": "/_etag/?",
        },
        {
            "path": "/vector/*"
        }
    ],
    "vectorIndexes": [
        {
            "path": "/vector",
            "type": "diskANN"
        }
    ]
}

Importante

Uma política de indexação de vetor deve estar no caminho definido na política de vetor do contêiner. Saiba mais sobre as políticas de vetor de contêiner.

Importante

O caminho do vetor adicionado à seção "excludedPaths" da política de indexação para garantir um desempenho otimizado para a inserção. Não adicionar o caminho do vetor a "excludedPaths" resultará em maior cobrança de RU e latência para inserções de vetores.

Índices espaciais

Ao definir um caminho espacial na política de indexação, você deve definir qual type de índice deve ser aplicado a esse caminho. Os tipos possíveis para índices espaciais incluem:

  • Point

  • Polygon

  • MultiPolygon

  • LineString

O Azure Cosmos DB, por padrão, não criará nenhum índice espacial. Se você quiser usar funções internas de SQL espaciais, deverá criar um índice espacial nas propriedades requeridas. Confira esta seção para obter exemplos na política de indexação de adição de índices espaciais.

Índices de tupla

Índices de tupla são úteis ao executar a filtragem em vários campos dentro de um elemento de matriz. Os índices de tupla são definidos na seção includedPaths da política de indexação usando o especificador de tupla "[]".

Observação

Ao contrário dos caminhos incluídos ou excluídos, você não pode criar um caminho com o curinga /*. Cada caminho de tupla precisa terminar com "/?". Se uma tupla em um caminho de tupla não existir em um item, um valor será adicionado ao índice para indicar que a tupla está indefinida.

Os caminhos de tupla de matriz serão definidos na seção includedPaths e usarão a notação a seguir.

<path prefix>/[]/{<tuple 1>, <tuple 2> … <tuple n>}/?

Observe que:

  • A primeira parte, o prefixo de caminho, é o caminho comum entre as tuplas. É o caminho da raiz para a matriz. Em nosso exemplo, é "/events".
  • Em seguida, está o especificador curinga de matriz "[]". Todos os caminhos de tupla de matriz devem ter um especificador curinga de matriz antes do especificador de tupla "{}".
  • Em seguida, está especificando as tuplas usando o especificador de tupla "{}".
  • As tuplas serão separadas por vírgula.
  • A tupla precisa usar a mesma especificação de caminho que outros caminhos de índice com algumas exceções:
  • As tuplas não devem começar com o "/" à esquerda.
  • As tuplas não devem ter curingas de matriz.
  • Tuplas não devem terminar em "?" ou “*”
  • “?” é o último segmento em um caminho de tupla e deve ser especificado imediatamente após o segmento especificador de tupla.

Por exemplo,

/events/[]/{name, category}/?

Estes são alguns exemplos de caminhos de tupla de matriz válidos:

    “includedPaths”:[  
        {“path”: “/events/[]/{name/first, name/last}/?”}, 
        {“path”: “/events/[]/{name/first, category}/?”}, 
        {“path”: “/events/[]/{name/first, category/subcategory}/?”}, 
        {“path”: “/events/[]/{name/[1]/first, category}/?”}, 
        {“path”: “/events/[]/{[1], [3]}/?”}, 
        {“path”: “/city/[1]/events/[]/{name, category}/?”} 
    ]

Estes são alguns exemplos de caminhos de tupla de matriz inválidos

  • /events/[]/{name/[]/first, category}/?
    • Uma das tuplas tem curinga de matriz
  • /events/[]/{name, category}/*
    • O último segmento no caminho da tupla de matriz deve ser "?" e não *
  • /events/[]/{{name, first},category}/?
    • O especificador de tupla está aninhado
  • /events/{name, category}/?
    • O curinga da matriz está ausente antes do especificador de tupla
  • /events/[]/{/name,/category}/?
    • Tuplas começam com /
  • /events/[]/{name/?,category/?}/?
    • Tuplas terminam com um ?
  • /city/[]/events/[]/{name, category}/?
    • O prefixo de caminho como curingas de matriz 2

Índices compostos

As consultas que têm uma cláusula ORDER BY com duas ou mais propriedades exigem um índice composto. Você também pode definir um índice composto para aprimorar o desempenho de várias consultas de igualdade e de intervalo. Por padrão, nenhum índice composto é definido, portanto, você deve adicionar índices compostos conforme necessário.

Ao contrário dos caminhos incluídos ou excluídos, você não pode criar um caminho com o curinga /*. Cada caminho composto tem um /? implícito no final do caminho que você não precisa especificar. Os caminhos compostos levam a um valor escalar que é o único valor incluído no índice composto. Se um caminho em um índice composto não existir em um item ou levar a um valor não escalar, um valor será adicionado ao índice para indicar que o caminho está indefinido.

Ao definir um índice composto, você especifica:

  • Dois ou mais caminhos de propriedade. A sequência na qual os caminhos de propriedade são definidos é importante.

  • A ordem (crescente ou decrescente).

Observação

Quando você adiciona um índice composto, a consulta utiliza índices de intervalo existentes até que a nova adição de índice composto seja concluída. Portanto, ao adicionar um índice composto, talvez você não observe imediatamente aprimoramentos no desempenho. É possível acompanhar o progresso da transformação de índice usando um dos SDKs.

Consultas ORDER BY em várias propriedades:

As seguintes considerações são utilizadas ao usar índices compostos para consultas com uma cláusula ORDER BY com duas ou mais propriedades.

  • Se os caminhos do índice composto não corresponderem à sequência das propriedades na cláusula ORDER BY, o índice composto não poderá dar suporte à consulta.

  • A ordem dos caminhos de índice composto (crescente ou decrescente) também deve corresponder ao order na cláusula ORDER BY.

  • O índice composto também dá suporte a uma cláusula ORDER BY com a ordem oposta em todos os caminhos.

Considere o seguinte exemplo em que um índice composto é definido nas propriedades name, age e _ts:

Índices compostos Consulta ORDER BY de exemplo Compatível com índice composto?
(name ASC, age ASC) SELECT * FROM c ORDER BY c.name ASC, c.age asc Yes
(name ASC, age ASC) SELECT * FROM c ORDER BY c.age ASC, c.name asc No
(name ASC, age ASC) SELECT * FROM c ORDER BY c.name DESC, c.age DESC Yes
(name ASC, age ASC) SELECT * FROM c ORDER BY c.name ASC, c.age DESC No
(name ASC, age ASC, timestamp ASC) SELECT * FROM c ORDER BY c.name ASC, c.age ASC, timestamp ASC Yes
(name ASC, age ASC, timestamp ASC) SELECT * FROM c ORDER BY c.name ASC, c.age ASC No

Você deve personalizar a política de indexação para que ela possa atender a todas as consultas ORDER BY necessárias.

Consultas com filtros em várias propriedades

Se uma consulta tiver filtros em duas ou mais propriedades, poderá ser útil criar um índice composto para essas propriedades.

Por exemplo, veja a seguinte consulta que tem um filtro de igualdade e de intervalo:

SELECT *
FROM c
WHERE c.name = "John" AND c.age > 18

Essa consulta será mais eficiente, levando menos tempo e consumindo menos RUs, se conseguir aplicar um índice composto em (name ASC, age ASC).

Consultas com vários filtros de intervalo também podem ser otimizadas com um índice composto. No entanto, cada índice composto individual só pode otimizar um filtro de intervalo. Os filtros de intervalo incluem >, <, <=, >= e !=. O filtro de intervalo deve ser definido por último no índice composto.

Veja a seguinte consulta com um filtro de igualdade e dois filtros de intervalo:

SELECT *
FROM c
WHERE c.name = "John" AND c.age > 18 AND c._ts > 1612212188

Essa consulta é mais eficiente com um índice composto em (name ASC, age ASC) e (name ASC, _ts ASC). No entanto, a consulta não utilizará um índice composto em (age ASC, name ASC) porque as propriedades com filtros de igualdade precisam ser definidas primeiro no índice composto. Dois índices compostos separados são necessários em vez de apenas um índice composto em (name ASC, age ASC, _ts ASC), pois cada índice composto só pode otimizar um filtro de intervalo.

As seguintes considerações são usadas ao criar índices compostos para consultas com filtros em várias propriedades

  • As expressões de filtro podem usar vários índices compostos.
  • As propriedades no filtro da consulta devem corresponder às do índice composto. Se uma propriedade estiver no índice composto, mas não for incluída na consulta como um filtro, a consulta não usará o índice composto.
  • Se uma consulta tiver outras propriedades no filtro que não foram definidas em um índice composto, uma combinação de índices compostos e intervalos é usada para avaliar a consulta. Isso exige menos RUs do que usar exclusivamente índices de intervalo.
  • Se uma propriedade tiver um filtro de intervalo (>, <, <=, >= ou !=), essa propriedade deverá ser definida por último no índice composto. Se uma consulta tiver mais de um filtro de intervalo, ela poderá se beneficiar de vários índices compostos.
  • Ao criar um índice composto para otimizar consultas com vários filtros, o ORDER do índice composto não terá impacto sobre os resultados. Essa propriedade é opcional.

Considere o seguinte exemplo em que um índice composto é definido nas propriedades name, age e timestamp:

Índices compostos Exemplo de consulta Compatível com índice composto?
(name ASC, age ASC) SELECT * FROM c WHERE c.name = "John" AND c.age = 18 Yes
(name ASC, age ASC) SELECT * FROM c WHERE c.name = "John" AND c.age > 18 Yes
(name ASC, age ASC) SELECT COUNT(1) FROM c WHERE c.name = "John" AND c.age > 18 Yes
(name DESC, age ASC) SELECT * FROM c WHERE c.name = "John" AND c.age > 18 Yes
(name ASC, age ASC) SELECT * FROM c WHERE c.name != "John" AND c.age > 18 No
(name ASC, age ASC, timestamp ASC) SELECT * FROM c WHERE c.name = "John" AND c.age = 18 AND c.timestamp > 123049923 Yes
(name ASC, age ASC, timestamp ASC) SELECT * FROM c WHERE c.name = "John" AND c.age < 18 AND c.timestamp = 123049923 No
(name ASC, age ASC) and (name ASC, timestamp ASC) SELECT * FROM c WHERE c.name = "John" AND c.age < 18 AND c.timestamp > 123049923 Yes

Consultas com um filtro e ORDER BY

Se uma consulta filtrar uma ou mais propriedades e tiver propriedades diferentes na cláusula ORDER BY, poderá ser útil adicionar as propriedades no filtro à cláusula ORDER BY.

Por exemplo, ao adicionar as propriedades no filtro à cláusula ORDER BY, a seguinte consulta pode ser reescrita para aplicar um índice composto:

Consulta que usa o índice de intervalo:

SELECT *
FROM c 
WHERE c.name = "John" 
ORDER BY c.timestamp

Consulta que usa o índice composto:

SELECT * 
FROM c 
WHERE c.name = "John"
ORDER BY c.name, c.timestamp

As mesmas otimizações de consulta podem ser generalizadas para qualquer consulta ORDER BY com filtros, tendo em mente que índices compostos individuais só podem dar suporte a, no máximo, um filtro de intervalo.

Consulta que usa o índice de intervalo:

SELECT * 
FROM c 
WHERE c.name = "John" AND c.age = 18 AND c.timestamp > 1611947901 
ORDER BY c.timestamp

Consulta que usa o índice composto:

SELECT * 
FROM c 
WHERE c.name = "John" AND c.age = 18 AND c.timestamp > 1611947901 
ORDER BY c.name, c.age, c.timestamp

Além disso, você pode usar índices compostos para otimizar consultas com funções do sistema e ORDER BY:

Consulta que usa o índice de intervalo:

SELECT * 
FROM c 
WHERE c.firstName = "John" AND Contains(c.lastName, "Smith", true) 
ORDER BY c.lastName

Consulta que usa o índice composto:

SELECT * 
FROM c 
WHERE c.firstName = "John" AND Contains(c.lastName, "Smith", true) 
ORDER BY c.firstName, c.lastName

As seguintes considerações se aplicam ao criar índices compostos para otimizar uma consulta com um filtro e uma cláusula ORDER BY:

  • Se você não definir um índice composto em uma consulta com um filtro em uma propriedade e uma cláusula ORDER BY separada usando uma propriedade diferente, a consulta ainda terá sucesso. No entanto, o custo de RU da consulta pode ser reduzido com um índice composto, especialmente se a propriedade na cláusula ORDER BY tiver uma cardinalidade alta.
  • Se a consulta filtrar propriedades, essas propriedades deverão ser incluídas primeiro na cláusula ORDER BY.
  • Se a consulta filtra várias propriedades, os filtros de igualdade precisam ser as primeiras propriedades na cláusula ORDER BY.
  • Se a consulta filtrar várias propriedades, você poderá ter no máximo um filtro de intervalo ou uma função de sistema utilizada por índice composto. A propriedade usada no filtro de intervalo ou na função do sistema deve ser definida por último no índice composto.
  • Todas as considerações para a criação de índices compostos em consultas ORDER BY com várias propriedades e consultas com filtros em várias propriedades ainda são aplicáveis.
Índices compostos Consulta ORDER BY de exemplo Compatível com índice composto?
(name ASC, timestamp ASC) SELECT * FROM c WHERE c.name = "John" ORDER BY c.name ASC, c.timestamp ASC Yes
(name ASC, timestamp ASC) SELECT * FROM c WHERE c.name = "John" AND c.timestamp > 1589840355 ORDER BY c.name ASC, c.timestamp ASC Yes
(timestamp ASC, name ASC) SELECT * FROM c WHERE c.timestamp > 1589840355 AND c.name = "John" ORDER BY c.timestamp ASC, c.name ASC No
(name ASC, timestamp ASC) SELECT * FROM c WHERE c.name = "John" ORDER BY c.timestamp ASC, c.name ASC No
(name ASC, timestamp ASC) SELECT * FROM c WHERE c.name = "John" ORDER BY c.timestamp ASC No
(age ASC, name ASC, timestamp ASC) SELECT * FROM c WHERE c.age = 18 and c.name = "John" ORDER BY c.age ASC, c.name ASC,c.timestamp ASC Yes
(age ASC, name ASC, timestamp ASC) SELECT * FROM c WHERE c.age = 18 and c.name = "John" ORDER BY c.timestamp ASC No

Consultas com um filtro e uma agregação

Se uma consulta filtrar uma ou mais propriedades e tiver uma função de sistema de agregação, poderá ser útil criar um índice composto para as propriedades na função do sistema de filtro e agregação. Essa otimização se aplica às funções do sistema SUM e AVG.

As considerações a seguir se aplicam ao criar índices compostos para otimizar uma consulta com um filtro e uma função do sistema de agregação.

  • Os índices compostos são opcionais ao executar consultas com agregações. No entanto, o custo de RU da consulta geralmente pode ser reduzido com um índice composto.
  • Se a consulta filtra várias propriedades, os filtros de igualdade precisam ser as primeiras propriedades no índice composto.
  • Você pode ter no máximo um filtro de intervalo por índice composto e ele precisa estar na propriedade na função do sistema de agregação.
  • A propriedade na função do sistema de agregação deve ser definida por último no índice composto.
  • A order (ASC ou DESC) não importa.
Índices compostos Exemplo de consulta Compatível com índice composto?
(name ASC, timestamp ASC) SELECT AVG(c.timestamp) FROM c WHERE c.name = "John" Yes
(timestamp ASC, name ASC) SELECT AVG(c.timestamp) FROM c WHERE c.name = "John" No
(name ASC, timestamp ASC) SELECT AVG(c.timestamp) FROM c WHERE c.name > "John" No
(name ASC, age ASC, timestamp ASC) SELECT AVG(c.timestamp) FROM c WHERE c.name = "John" AND c.age = 25 Yes
(age ASC, timestamp ASC) SELECT AVG(c.timestamp) FROM c WHERE c.name = "John" AND c.age > 25 No

Índices compostos com um curinga de matriz

Veja abaixo um exemplo para um índice composto que contém um curinga de matriz.

{  
    "automatic":true,
    "indexingMode":"Consistent",
    "includedPaths":[  
        {  
            "path":"/*"
        }
    ],
    "excludedPaths":[],
    "compositeIndexes":[  
        [  
            {"path":"/familyname", "order":"ascending"},
            {"path":"/children/[]/age", "order":"descending"}
        ]
    ]
}

Uma consulta de exemplo que pode se beneficiar desse índice composto é:

SELECT r.id
FROM root r
JOIN ch IN r.children
WHERE r.familyname = 'Anderson' AND ch.age > 20

Modificando a política de indexação

A política de indexação de um contêiner pode ser atualizada a qualquer momento usando o portal do Azure ou um dos SDKs com suporte. Uma atualização para a política de indexação dispara uma transformação do índice antigo para o novo, que é executada online e in-loco (portanto, nenhum espaço de armazenamento extra é consumido durante a operação). A política de indexação antiga é transformada com eficiência na nova política, sem afetar a disponibilidade de gravação, de leitura e nem a taxa de transferência provisionada no contêiner. A transformação de índice é uma operação assíncrona e o tempo necessário para conclui-la depende da taxa de transferência provisionada, do número de itens e do tamanho deles. Se várias atualizações de política de indexação precisarem ser feitas, recomenda-se fazer todas as alterações como uma única operação para que a transformação de índice seja concluída o mais rápido possível.

Importante

A transformação de índice é uma operação que consome unidades de solicitação.

Observação

Você pode acompanhar o progresso da transformação de índice no portal do Azure ou usando um dos SDKs.

Não há nenhum impacto na disponibilidade de gravação durante as transformações de índice. A transformação do índice usa as RUs provisionadas, mas com uma prioridade mais baixa do que as suas consultas ou operações CRUD.

Não há nenhum impacto na disponibilidade de leitura ao adicionar novos caminhos de índice. As consultas só utilizarão novos caminhos de índice depois que a transformação do índice for concluída. Em outras palavras, ao adicionar um novo caminho indexado, as consultas que se beneficiam desse caminho indexado terão o mesmo desempenho antes e durante a transformação do índice. Após a conclusão da transformação do índice, o mecanismo de consulta começará a usar os novos caminhos indexados.

Ao remover caminhos indexados, você deve agrupar todas as alterações em uma transformação de política de indexação. Se você remover vários índices e fizer isso em apenas uma alteração de política de indexação, o mecanismo de consulta fornecerá resultados consistentes e completos em toda a transformação de índice. No entanto, se você remover índices por meio de várias alterações de política de indexação, o mecanismo de consulta não fornecerá resultados consistentes nem completos até que todas as transformações de índice sejam concluídas. A maioria dos desenvolvedores não remove índices e tenta imediatamente executar consultas que utilizam esses índices, portanto, na prática, essa situação é improvável.

Quando você remove um caminho indexado, o mecanismo de consulta para imediatamente de usá-lo, e fará um exame completo em vez disso.

Observação

Quando possível, você sempre deve tentar agrupar várias remoções de índice em uma única modificação de política de indexação.

Importante

A remoção de um índice entra em vigor imediatamente, enquanto a adição de um novo índice leva algum tempo, pois requer uma transformação de indexação. Ao substituir um índice por outro (por exemplo, substituindo um único índice de propriedades por um índice composto), adicione o novo índice primeiro e aguarde até que a transformação de índice seja concluída antes de remover o índice anterior da política de indexação. Caso contrário, isso afetará negativamente sua capacidade de consultar o índice anterior e poderá interromper todas as cargas de trabalho ativas que o referenciam.

Indexação de políticas e TTL

O uso do recurso TTL (vida útil) requer indexação. Isso significa que:

  • não é possível ativar o TTL em um contêiner no qual o modo de indexação está definido como none,
  • não é possível definir o modo de indexação como Nenhum em um contêiner no qual o TTL está ativado.

Em cenários em que nenhum caminho de propriedade precisa ser indexado, mas o TTL é necessário, você pode usar uma política de indexação com um modo de indexação definido como consistent, sem caminhos incluídos, e /* como o único caminho excluído.