Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
O Cosmos DB (em Azure e Fabric) é um banco de dados independente de esquema que permite iterar em seu aplicativo sem precisar lidar com o gerenciamento de esquema ou índice. Essa funcionalidade também é conhecida como schema on read, o que significa que o Cosmos DB não impõe um esquema nos seus dados ao serem gravados no banco de dados. Seu esquema é definido nas classes que você cria em seu aplicativo à medida que desserializa dados do banco de dados durante operações de leitura ou gravação.
A indexação no Cosmos DB em Microsoft Fabric foi projetada para fornecer desempenho de consulta rápido e flexível, independentemente de como os dados evoluem. Por padrão, o Cosmos DB indexa automaticamente cada propriedade para todos os itens em seu contêiner sem precisar definir nenhum esquema ou configurar índices secundários.
Árvore conceitual
Sempre que um item é armazenado em um contêiner, seu conteúdo é projetado como um documento JSON e, depois, convertido em uma representação de árvore. Essa conversão significa que todas as propriedades do item em questão são representadas como um nó em uma árvore. Um pseudo nó raiz é criado como um pai para todas as propriedades de primeiro nível do item. Os nós folha contêm os valores escalares reais que um item transporta.
Por exemplo, considere este item:
{
"id": "00000000-0000-0000-0000-000000004368",
"name": "Cofaz Jacket",
"tags": [
{ "category": "clothing", "type": "jacket" },
{ "category": "outdoor", "type": "winter" }
],
"inventory": { "warehouse": "Seattle", "quantity": 50 },
"distributors": [
{ "name": "Contoso" },
{ "name": "AdventureWorks" }
]
}
Esta árvore conceitual representa o item JSON de exemplo:
-
id:00000000-0000-0000-0000-000000004368 -
name:Cofaz Jacket tags0-
category:clothing -
type:jacket
-
1-
category:outdoor -
type:winter
-
inventory-
warehouse:Seattle -
quantity:50
-
distributors0-
name:Contoso
-
1-
name:AdventureWorks
-
Preste atenção em como as matrizes são codificadas na árvore: cada entrada em uma matriz obtém um nó intermediário rotulado com o índice dessa entrada dentro da matriz. Por exemplo, a primeira entrada é 0 e a segunda entrada é 1.
Caminhos de propriedade
O Cosmos DB transforma itens em árvores porque permite que o sistema referencie propriedades usando seus caminhos dentro dessas árvores. Para obter o caminho para uma propriedade, podemos percorrer a árvore do nó raiz até essa propriedade e concatenar os rótulos de cada nó atravessado.
Vejamos os caminhos para cada propriedade do exemplo de item descrito acima:
| Caminho | Value |
|---|---|
/id |
"00000000-0000-0000-0000-000000004368" |
/name |
"Cofaz Jacket" |
/tags/0/category |
"clothing" |
/tags/0/type |
"jacket" |
/tags/1/category |
"outdoor" |
/tags/1/type |
"winter" |
/inventory/warehouse |
"Seattle" |
/inventory/quantity |
50 |
/distributors/0/name |
"Contoso" |
/distributors/1/name |
"AdventureWorks" |
O Cosmos DB indexa efetivamente o caminho de cada propriedade e seu valor correspondente quando um item é gravado.
Tipos de índice no Cosmos DB
Atualmente, o Cosmos DB dá suporte a quatro tipos de índices.
Você pode configurar esses tipos de índice ao definir a política de indexação.
Índice de intervalo
Os índices de range são baseados em uma estrutura de árvore ordenada. O tipo de índice de intervalo é usado para:
Consultas de igualdade:
SELECT * FROM container c WHERE c.property = 'value'SELECT * FROM container c WHERE c.property IN ("value1", "value2", "value3")Correspondência de igualdade em um elemento de matriz
SELECT * FROM container c WHERE ARRAY_CONTAINS(c.tags, "tag1")Consultas de intervalo:
SELECT * FROM container c WHERE c.property > 0Observação
Funciona para
>,<, ,>=,<=!=Verificando a presença de uma propriedade:
SELECT * FROM container c WHERE IS_DEFINED(c.property)Funções do sistema de cadeia de caracteres:
SELECT * FROM container c WHERE CONTAINS(c.property, "value")SELECT * FROM container c WHERE STRINGEQUALS(c.property, "value")Consultas
ORDER BY:SELECT * FROM container c ORDER BY c.propertyConsultas
JOIN:SELECT d FROM container c JOIN d IN c.properties WHERE d = 'value'
Os índices de intervalo podem ser usados em valores escalares (cadeia de caracteres ou número). A política de indexação padrão para contêineres recém-criados impõe os índices de intervalo para qualquer cadeia de caracteres ou número.
Observação
Uma ORDER BY cláusula que é ordenada por uma única propriedade sempre precisa de um índice de intervalo e falha se o caminho referenciado não tiver um. Da mesma forma, uma ORDER BY consulta que é ordenada por várias propriedades sempre precisa de um índice composto.
Índice espacial
Índices espaciais permitem consultas eficientes em objetos geoespaciais, como pontos, linhas, polígonos e vários polígonos. Essas consultas usam ST_DISTANCEST_WITHINST_INTERSECTS palavras-chave. Veja a seguir alguns exemplos que usam o tipo de índice espacial:
Consultas de distâncias geoespaciais
SELECT * FROM container c WHERE ST_DISTANCE(c.property, { "type": "Point", "coordinates": [0.0, 10.0] }) < 40Geoespacial nas consultas:
SELECT * FROM container c WHERE ST_WITHIN(c.property, {"type": "Point", "coordinates": [0.0, 10.0] })Consultas de interseção geoespacial:
SELECT * FROM container c WHERE ST_INTERSECTS(c.property, { 'type':'Polygon', 'coordinates': [[ [31.8, -5], [32, -5], [31.8, -5] ]] })
Índices espaciais podem ser usados em objetos GeoJSON formatados corretamente. Pontos, LineStrings, polígonos e multipolígonos são suportados atualmente.
Índice composto
Os índices compostos aumentam a eficiência quando você está executando operações em diversos campos. O tipo de índice composto é usado para:
Consultas
ORDER BYem múltiplas propriedades:SELECT * FROM container c ORDER BY c.property1, c.property2Consultas com um filtro e
ORDER BY. Essas consultas poderão utilizar um índice composto se a propriedade de filtro for adicionada à cláusulaORDER BY.SELECT * FROM container c WHERE c.property1 = 'value' ORDER BY c.property1, c.property2Consultas com um filtro em duas ou mais propriedades em que pelo menos uma propriedade é um filtro de igualdade:
SELECT * FROM container c WHERE c.property1 = 'value' AND c.property2 > 'value'
Desde que um predicado de filtro use um dos tipos de índice, o mecanismo de consulta avalia isso primeiro antes de verificar o restante. Por exemplo, se você tiver uma consulta SQL, como SELECT * FROM c WHERE c.department = "Information Technology" and CONTAINS(c.team, "Pilot"):
Essa consulta primeiro aplica um filtro para entradas onde
department = "Information Technology"por meio do uso do índice. Em seguida, ele passa todas asdepartment = "Information Technology"entradas por meio de um pipeline subsequente para avaliar o filtro de predicadoCONTAINS.Você pode acelerar as consultas e evitar verificações completas de contêiner ao usar funções que executam uma verificação completa como
CONTAINS. Você pode adicionar mais predicados de filtro que usam o índice para acelerar essas consultas. A ordem das cláusulas de filtro não é importante. O mecanismo de consulta entende quais predicados são mais seletivos e executa a consulta de acordo.
Índice vetorial
Índices de vetores aumentam a eficiência ao realizar buscas em vetores usando a função de sistema VECTORDISTANCE. As pesquisas de vetor têm menor latência, maior taxa de transferência e menor consumo de RU ao usar um índice de vetor. O Cosmos DB dá suporte a quaisquer inserções de vetor (texto, imagem, multimodal etc.) em 4.096 dimensões de tamanho.
ORDER BYconsultas de busca em vetores:SELECT TOP 10 * FROM container c ORDER BY VECTORDISTANCE(c.vector1, c.vector2)Projeção da pontuação de similaridade em consultas de busca em vetores:
SELECT TOP 10 c.name, VECTORDISTANCE(c.vector1, c.vector2) AS score FROM container c ORDER BY VECTORDISTANCE(c.vector1, c.vector2)Filtros de intervalo na pontuação de similaridade.
SELECT TOP 10 * FROM container c WHERE VECTORDISTANCE(c.vector1, c.vector2) > 0.8 ORDER BY VECTORDISTANCE(c.vector1, c.vector2)
Observação
Em geral, você pode adicionar novas configurações de caminho ou remover as existentes, mas não pode alterar as configurações de uma política de vetor de embedding ou uma política de vetor de indexação. Para fazer isso, primeiro você deve descartar a política de vetor e o índice existentes e, em seguida, adicioná-lo novamente com a nova configuração.
Como as consultas usam índices
Há cinco maneiras pelas quais o mecanismo de consulta pode avaliar filtros de consulta, classificados dos mais eficientes para os menos eficientes:
- Busca de índice
- Verificação de índice precisa
- Verificação de índice expandida
- Escaneamento completo do índice
- Verificação completa
Quando você indexa caminhos de propriedade, o mecanismo de consulta automaticamente usa o índice da maneira mais eficiente possível. Além de indexar novos caminhos de propriedade, você não precisa configurar nada para otimizar como as consultas usam o índice. A carga de RU de uma consulta é uma combinação da carga de RU do uso do índice e da carga de RU do carregamento de itens.
A tabela a seguir resume as diferentes maneiras pelas quais os índices são usados no Cosmos DB:
| Tipo de pesquisa | Description | Exemplos comuns | Cobrança pelo uso do índice | Custos do carregamento de itens do armazenamento de dados transacionais |
|---|---|---|---|---|
| Busca de índice | Lê somente os valores indexados necessários e carrega somente itens correspondentes do armazenamento de dados transacional | Filtros de igualdade, IN | Filtro de constante por igualdade | Aumenta com base no número de itens nos resultados da consulta |
| Verificação precisa do índice | Pesquisa binária de valores indexados que carrega somente itens correspondentes do armazenamento de dados transacional | Comparações de intervalo (>, <, <=, ou >=), StartsWith | Comparável a uma busca por índice, aumenta ligeiramente dependendo da cardinalidade das propriedades indexadas | Aumenta com base no número de itens nos resultados da consulta |
| Verificação de índice expandida | Pesquisa otimizada (mas menos eficiente do que uma pesquisa binária) de valores indexados que carrega apenas itens correspondentes do armazenamento de dados transacional | StartsWith (não diferencia maiúsculas de minúsculas), StringEquals (não diferencia maiúsculas de minúsculas) | Aumenta ligeiramente com base na cardinalidade das propriedades indexadas | Aumenta com base no número de itens nos resultados da consulta |
| Verificação de índice completa | Lê o conjunto distinto de valores indexados e carrega somente itens correspondentes do armazenamento de dados transacional | Contains (contém), EndsWith (termina com), RegexMatch (correspondência regex), LIKE (como) | Aumenta linearmente com base na cardinalidade de propriedades indexadas | Aumenta com base no número de itens nos resultados da consulta |
| Verificação completa | Carregar todos os itens do armazenamento de dados transacionais | Superiores, Inferiores | N/A | Aumenta com base no número de itens no contêiner |
Ao escrever consultas, você deve usar predicados de filtro que utilizem o índice da maneira mais eficiente possível. Por exemplo, se StartsWith ou Contains funcionar para o seu caso de uso, você deverá optar por StartsWith, já que isso fará uma verificação de índice precisa em vez de uma verificação de índice completa.
Detalhes de uso do índice
Dica
Esta seção aborda mais detalhes sobre como as consultas usam índices. Esse nível de detalhes não é necessário para aprender a começar a usar o Cosmos DB, mas está documentado em detalhes para usuários curiosos. Vamos mencionar o exemplo de item compartilhado no início deste documento:
Considere estes dois itens de exemplo:
[
{
"id": "00000000-0000-0000-0000-000000004368",
"name": "Cofaz Jacket",
"tags": [
{ "category": "clothing", "type": "jacket" },
{ "category": "outdoor", "type": "winter" }
],
"inventory": { "warehouse": "Seattle", "quantity": 50 },
"distributors": [
{ "name": "Contoso" },
{ "name": "AdventureWorks" }
]
},
{
"id": "00000000-0000-0000-0000-000000004002",
"name": "Potana bike",
"tags": [
{ "category": "cycling", "type": "mountain" }
],
"inventory": { "warehouse": "Seattle", "quantity": 30 },
"distributors": [
{ "name": "Contoso" },
{ "name": "Fabrikam" },
{ "name": "Northwind" }
]
}
]
O Cosmos DB usa um índice invertido. O índice funciona mapeando cada caminho JSON para o conjunto de itens que contêm esse valor. O mapeamento de ID do item é representado em várias páginas de índice diferentes para o contêiner. Aqui está um diagrama de amostra de um índice invertido para um contêiner que inclui os dois itens de exemplo.
| Caminho | Value | Lista de identificadores de itens |
|---|---|---|
/tags/0/category |
clothing |
[00000000-0000-0000-0000-000000004368] |
/tags/0/category |
cycling |
[00000000-0000-0000-0000-000000004002] |
/tags/0/type |
jacket |
[00000000-0000-0000-0000-000000004368] |
/tags/0/type |
mountain |
[00000000-0000-0000-0000-000000004002] |
/tags/1/category |
outdoor |
[00000000-0000-0000-0000-000000004368] |
/tags/1/type |
winter |
[00000000-0000-0000-0000-000000004368] |
/inventory/warehouse |
Seattle |
[00000000-0000-0000-0000-000000004368, 00000000-0000-0000-0000-000000004002] |
/inventory/quantity |
30 |
[00000000-0000-0000-0000-000000004002] |
/inventory/quantity |
50 |
[00000000-0000-0000-0000-0000-000000004001] |
O índice invertido tem dois atributos importantes:
Para um caminho, os valores são classificados em ordem crescente. Portanto, o mecanismo de consulta pode facilmente servir
ORDER BYdo índice.Para um determinado caminho, o mecanismo de consulta pode examinar o conjunto distinto de valores possíveis para identificar as páginas de índice em que há resultados.
O mecanismo de consulta pode utilizar o índice invertido de quatro maneiras diferentes:
Busca de índice
Considere a consulta a seguir:
SELECT
tag
FROM
tag IN product.tags
WHERE
tag.category = 'outdoor'
O predicado da consulta (filtragem em itens nos quais qualquer etiqueta tem "outdoor" como sua categoria) corresponderia ao caminho destacado aqui:
tags1-
category:outdoor
-
Como essa consulta tem um filtro de igualdade, depois de percorrer essa árvore, podemos identificar rapidamente as páginas de índice que contêm os resultados da consulta. Nesse caso, o mecanismo de consulta leria páginas de índice que contêm Item 00000000-0000-0000-0000-000000004368. Uma busca de índice é a maneira mais eficiente de usar o índice. Com uma busca de índice, lemos apenas as páginas de índice necessárias e carregamos apenas os itens nos resultados da consulta. Portanto, o tempo de pesquisa de índice e o custo de unidade de solicitação (RU) da pesquisa de índice são incrivelmente baixos, independentemente do volume total de dados.
Verificação de índice precisa
Considere a consulta a seguir:
SELECT
*
FROM
product
WHERE
product.inventory.quantity > 30
O predicado de consulta (filtragem em itens em que há mais de 30 unidades no inventário) pode ser avaliado com uma verificação de índice precisa do inventory/quantity caminho. Ao fazer uma verificação de índice precisa, o mecanismo de consulta começa fazendo uma pesquisa binária do conjunto distinto de valores possíveis para encontrar a localização do valor 30 do caminho inventory/quantity. Como os valores de cada caminho são classificados em ordem crescente, é fácil para o motor de consulta fazer uma busca binária. Depois que o mecanismo de consulta encontra o valor 30, ele começa a ler todas as páginas de índice restantes (seguindo na direção crescente).
Como o mecanismo de consulta pode fazer uma pesquisa binária para evitar a verificação de páginas de índice desnecessárias, as verificações de índice precisas tendem a ter latências e cobranças de RU comparáveis às operações de busca de índice.
Verificação de índice expandida
Considere a consulta a seguir:
SELECT
*
FROM
product
WHERE
STARTSWITH(product.inventory.warehouse, "Sea", true)
O predicado de consulta (filtragem de itens que têm inventário em um armazém começando com "Sea", sem diferença entre maiúsculas e minúsculas) pode ser avaliado com uma verificação de índice expandida no caminho inventory/warehouse. As operações que fazem uma varredura de índice expandida têm otimizações que podem ajudar a evitar a necessidade de escanear cada página do índice, mas são ligeiramente mais custosas do que a busca binária de uma verificação de índice precisa.
Por exemplo, ao avaliar StartsWith sem diferenciar maiúsculas de minúsculas, o mecanismo de consulta verifica o índice para diferentes combinações possíveis de valores em maiúsculas e minúsculas. Essa otimização permite que o mecanismo de consulta evite ler a maioria das páginas de índice. Diferentes funções do sistema têm otimizações diferentes que podem ser usadas para evitar a leitura de cada página de índice, de modo que sejam categorizadas de forma mais ampla como uma verificação de índice expandida.
Escaneamento completo do índice
Considere a consulta a seguir:
SELECT
*
FROM
product
WHERE
CONTAINS(product.inventory.warehouse, "eat")
O predicado de consulta (filtragem em item que possui inventário em um armazém que contém "eat") pode ser avaliado com uma verificação de índice do caminho inventory/warehouse. Ao contrário de uma verificação de índice precisa, uma verificação de índice completa sempre irá verificar o conjunto distinto de valores possíveis para identificar as páginas de índice nas quais existam resultados. Nesse caso, CONTAINS é executado no índice. O tempo de pesquisa de índice e o preço da RU para verificações de índice aumenta à medida que a cardinalidade do caminho aumenta. Em outras palavras, quanto mais valores distintos possíveis o mecanismo de consulta precisa escanear, maior serão a latência e o custo em RUs envolvidos na realização de uma verificação de índice completa.
Por exemplo, considere duas propriedades: name e warehouse. A cardinalidade do nome é 5.000 e a cardinalidade de warehouse 200. Aqui estão duas consultas de exemplo, cada uma das quais tem uma CONTAINS função do sistema que realiza uma verificação de índice completa na propriedade name. A primeira consulta usa mais RUs (unidades de solicitação) do que a segunda consulta porque a cardinalidade do nome é maior que warehouse.
SELECT
*
FROM
container c
WHERE
CONTAINS(c.name, "Pack", false)
SELECT
*
FROM
c
WHERE
CONTAINS(c.inventory.warehouse, "Sea", false)
Verificação completa
Em alguns casos, o mecanismo de consulta pode não ser capaz de avaliar um filtro de consulta usando o índice. Nesse caso, o mecanismo de consulta precisa carregar todos os itens do armazenamento transacional para avaliar o filtro da consulta. As verificações completas não usam o índice e têm uma cobrança de RU que aumenta linearmente com o tamanho total dos dados. Felizmente, as operações que exigem verificações completas são raras.
Consultas de busca em vetores sem um índice de vetor definido
Se você não definir uma política de índice de vetor e usar a função do VECTORDISTANCE sistema em uma ORDER BY cláusula, essa consulta resultará em uma varredura completa e terá uma cobrança de RU maior do que se você tivesse definido uma política de índice de vetor. Similaridade, se você usar VECTORDISTANCE com o valor booliano de força bruta definido como true e não tiver um flat índice definido para o caminho do vetor, ocorrerá uma verificação completa.
Consultas com expressões de filtro complexas
Nos exemplos anteriores, só consideramos consultas que tinham expressões de filtro simples (por exemplo, consultas com apenas um único filtro de igualdade ou intervalo). Na realidade, a maioria das consultas tem expressões de filtro muito mais complexas.
Considere a consulta a seguir:
SELECT
*
FROM
product
WHERE
product.inventory.quantity = 50 AND CONTAINS(product.inventory.warehouse, "Sea")
Para executar essa consulta, o mecanismo de consulta deve fazer uma busca de índice em inventory/quantity e uma verificação de índice completo em inventory/warehouse. O mecanismo de consulta tem uma heurística interna que ele usa para avaliar a expressão de filtro de consulta da forma mais eficiente possível. Nesse caso, o mecanismo de consulta evitaria a necessidade de ler páginas de índice desnecessárias ao fazer a busca de índice primeiro. Por exemplo, se apenas 50 itens correspondessem ao filtro de igualdade, o mecanismo de consulta só precisaria avaliar CONTAINS nas páginas de índice que contivessem esses 50 itens. Uma verificação de índice completa de todo o contêiner não seria necessária.
Utilização de índice para funções de agregação escalares
As consultas com funções de agregação devem depender exclusivamente do índice para usá-lo.
Em alguns casos, o índice pode retornar falsos positivos. Por exemplo, ao avaliar CONTAINS no índice, o número de correspondências no índice pode exceder o número de resultados da consulta. O mecanismo de consulta carrega todas as correspondências de índice, avalia o filtro nos itens carregados e retorna apenas os resultados corretos.
Para a maioria das consultas, carregar as correspondências de índice com falsos positivos não exercerá nenhum impacto perceptível sobre a utilização do índice.
Por exemplo, considere a seguinte consulta:
SELECT
*
FROM
product
WHERE
CONTAINS(product.inventory.warehouse, "Sea")
A CONTAINS função do sistema pode retornar algumas correspondências falsas positivas, portanto, o mecanismo de consulta precisa verificar se cada item carregado corresponde à expressão de filtro. Neste exemplo, o mecanismo de consulta pode precisar carregar apenas alguns itens extras, portanto, o efeito na utilização do índice e na carga de RU é mínimo.
No entanto, as consultas com funções de agregação devem depender exclusivamente do índice para usá-lo. Por exemplo, considere a seguinte consulta com um agregado COUNT:
SELECT
COUNT(1)
FROM
product
WHERE
CONTAINS(product.inventory.warehouse, "Sea")
Como no primeiro exemplo, a função do sistema CONTAINS pode retornar algumas correspondências falsas positivas. No entanto, ao contrário da consulta SELECT *, a consulta COUNT não pode avaliar a expressão de filtro nos itens carregados para verificar todas as correspondências de índice. A consulta COUNT deve depender exclusivamente do índice, de forma que, se houver uma possibilidade de que uma expressão de filtro retorne correspondências com falsos positivos, o mecanismo de consulta recorra a uma verificação completa.
As consultas com as seguintes funções de agregação devem depender exclusivamente do índice, portanto, avaliar algumas funções do sistema requer uma verificação completa.
Conteúdo relacionado
- Políticas de indexação no Cosmos DB (em Azure e Fabric)
- as políticas de indexação de exemplo no Cosmos DB (em Azure e Fabric)