Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
O Cosmos DB é um banco de dados sem esquema que permite fazer iterações na aplicação sem ter de lidar com a gestão de esquemas ou índices. Isto também é referido como schema na leitura, significando que o Cosmos DB não aplica um esquema aos seus dados quando estes são escritos na base de dados. Em vez disso, o seu esquema é projetado nas classes que define dentro da sua aplicação quando desserializa dados da base de dados ao ler ou consultar os seus dados.
A indexação no Cosmos DB no Microsoft Fabric foi projetada para oferecer um desempenho de consulta rápido e flexível, independentemente de como seus dados evoluem. Por padrão, o Cosmos DB indexa automaticamente todas as propriedades de todos os itens em seu contêiner sem precisar definir nenhum esquema ou configurar índices secundários.
Árvore conceptual
Sempre que um item é armazenado em um contêiner, seu conteúdo é projetado como um documento JSON e, em seguida, convertido em uma representação em árvore. Essa conversão significa que cada propriedade desse item é representada como um nó em uma árvore. Um pseudonó raiz é criado como um pai para todas as propriedades de primeiro nível do item. Os nós de folha contêm os valores escalares reais possuídos por um item.
Como exemplo, considere este item:
{
"locations": [
{
"country": "Germany",
"city": "Berlin"
},
{
"country": "France",
"city": "Paris"
}
],
"headquarters": {
"country": "Belgium",
"employees": 250
},
"exports": [
{
"city": "Moscow"
},
{
"city": "Athens"
}
]
}
Esta árvore conceitual representa o item JSON de exemplo:
locations0-
country:Germany -
city:Berlin
-
1-
country:France -
city:Paris
-
headquarters-
country:Belgium -
employees:250
-
exports0-
city:Moscow
-
1-
city:Athens
-
O diagrama de árvore mostra um nó raiz com três ramos: "locais", "quartel-general" e "exportações". "Localizações" divide-se em dois nós numerados, cada um com dois subnós relacionados com a localização ("Alemanha ou Berlim" e "França ou Paris"). "Sede" tem "Bélgica" para sua localização e "funcionários" ("250"). As "Exportações" dividem-se em dois nós numerados, cada um com um subnó "cidade" ("Moscovo" e "Atenas").
Preste atenção em como as matrizes são codificadas na árvore: cada entrada em uma matriz recebe 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 da propriedade
O Cosmos DB transforma itens em árvores porque permite que o sistema faça referência a 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ó percorrido.
Aqui estão os caminhos para cada propriedade do item de exemplo descrito anteriormente:
| Caminho | Valor |
|---|---|
/locations/0/country |
"Germany" |
/locations/0/city |
"Berlin" |
/locations/1/country |
"France" |
/locations/1/city |
"Paris" |
/headquarters/country |
"Belgium" |
/headquarters/employees |
250 |
/exports/0/city |
"Moscow" |
/exports/1/city |
"Athens" |
O Cosmos DB indexa efetivamente o caminho de cada propriedade e seu valor correspondente quando um item é gravado.
Tipos de índice
Atualmente, o Cosmos DB suporta 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 intervalo são baseados em uma estrutura ordenada semelhante a uma árvore. Este é o tipo de índice padrão e não precisa de ser especificado ao definir uma política de índice. O tipo de índice de intervalo é usado para:
Questões 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
Compatível com
>,<,>=,<=,!=Verificação da presença de um imóvel:
SELECT * FROM container c WHERE IS_DEFINED(c.property)Funções do sistema de strings:
SELECT * FROM container c WHERE CONTAINS(c.property, "value")SELECT * FROM container c WHERE STRINGEQUALS(c.property, "value")ORDER BYConsultas:SELECT * FROM container c ORDER BY c.propertyJOINConsultas:SELECT d FROM container c JOIN d IN c.properties WHERE d = 'value'
Os índices de intervalo podem ser usados em valores escalares (string ou número). A política de indexação predefinida para os contentores recém-criados impõe índices de intervalo para qualquer cadeia ou número.
Observação
Uma ORDER BY cláusula que ordena por uma única propriedade sempre precisa de um índice de intervalo e falha se o caminho ao qual ela faz referência não tiver um. Da mesma forma, uma ORDER BY consulta ordenada por várias propriedades sempre precisa de um índice composto.
Índice espacial
Os índices espaciais permitem consultas eficientes em objetos geoespaciais, como pontos, linhas, polígonos e multipolígonos. Essas consultas usam ST_DISTANCE, ST_WITHIN, ST_INTERSECTS palavras-chave. A seguir estão alguns exemplos que usam o tipo de índice espacial:
Consultas de distância geoespacial:
SELECT * FROM container c WHERE ST_DISTANCE(c.property, { "type": "Point", "coordinates": [0.0, 10.0] }) < 40Geoespacial dentro das consultas:
SELECT * FROM container c WHERE ST_WITHIN(c.property, {"type": "Point", "coordinates": [0.0, 10.0] })Consultas de intersecção geoespacial:
SELECT * FROM container c WHERE ST_INTERSECTS(c.property, { 'type':'Polygon', 'coordinates': [[ [31.8, -5], [32, -5], [31.8, -5] ]] })
Os índices espaciais podem ser usados em objetos GeoJSON formatados corretamente. Atualmente, há suporte para Points, LineStrings, Polygons e MultiPolygons.
Índice composto
Os índices compostos aumentam a eficiência quando você executa operações em vários campos. O tipo de índice composto é usado para:
ORDER BYConsultas sobre várias propriedades:SELECT * FROM container c ORDER BY c.property1, c.property2Consultas com um filtro e
ORDER BY. Essas consultas podem utilizar um índice composto se a propriedade filter for adicionadaORDER BYà cláusula.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"):
Esta consulta primeiro aplica um filtro para entradas onde
department = "Information Technology"usando o índice. Em seguida, ele passa todas asdepartment = "Information Technology"entradas por um pipeline subsequente para avaliar o predicado doCONTAINSfiltro.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 descobre quais predicados são mais seletivos e executa a consulta de acordo.
Índice vetorial
Os índices vetoriais aumentam a eficiência ao realizar pesquisas vetoriais usando a função do VECTORDISTANCE sistema. As pesquisas vetoriais têm menor latência, maior taxa de transferência e menor consumo de RU ao usar um índice vetorial. O Cosmos DB suporta qualquer incorporação vetorial (texto, imagem, multimodal, etc.) com menos de 4.096 dimensões de tamanho.
ORDER BYConsultas de pesquisa vetorial:SELECT TOP 10 * FROM container c ORDER BY VECTORDISTANCE(c.vector1, c.vector2)Projeção do escore de similaridade em consultas de busca vetorial:
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)
Importante
Políticas vetoriais e índices vetoriais são imutáveis após a criação. Para fazer alterações, crie uma nova coleção.
Utilização do índice
Há cinco maneiras pelas quais o mecanismo de consulta pode avaliar filtros de consulta, classificados do mais eficiente para o menos eficiente:
- Busca de índice
- Varredura precisa do índice
- Verificação de índice expandida
- Verificação completa do índice
- Análise completa
Quando você indexa caminhos de propriedade, o mecanismo de consulta usa automaticamente o índice da forma 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 cobrança de RU de uma consulta é uma combinação da cobrança de RU do uso do índice e da cobrança de RU do carregamento de itens.
A tabela a seguir resume as diferentes maneiras como os índices são usados no Cosmos DB:
| Tipo de pesquisa | Descrição | Exemplos comuns | Cobrança baseada no uso do índice | Encargos de carregamento de itens a partir do armazenamento de dados transacionais |
|---|---|---|---|---|
| Busca de índice | Leia apenas os valores indexados necessários e carregue somente os itens correspondentes da loja de dados transacionais. | Filtros de igualdade, IN | Constante para filtro de igualdade | Aumenta com base no número de itens nos resultados da consulta |
| Varredura precisa do índice | Pesquisa binária de valores indexados e carregar apenas itens correspondentes do armazenamento de dados transacionais | Comparações de intervalo (>, <, <=, ou >=), StartsWith | Comparável a uma consulta por índice, 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 expandida | Pesquisa otimizada (mas menos eficiente do que uma pesquisa binária) de valores indexados e carregar apenas itens correspondentes do armazenamento de dados transacionais | 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 completa do índice | Leia um conjunto distinto de valores indexados e carregue apenas itens correspondentes do armazenamento de dados transacionais | Contém, EndsWith, RegexMatch, LIKE | Aumenta linearmente com base na cardinalidade das 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 | Superior, Inferior | N/A | Aumentos com base no número de itens no contêiner |
Ao escrever consultas, você deve usar predicados de filtro que usam o índice da forma mais eficiente possível. Por exemplo, se um ou StartsWithContains funcionaria para o seu caso de uso, você deve optar por StartsWith uma vez que ele faz uma verificação de índice precisa em vez de uma verificação de índice completa.
Detalhes de utilização do índice
Sugestão
Esta seção aborda mais detalhes sobre como as consultas usam índices. Esse nível de detalhe não é necessário para aprender como começar a usar o Cosmos DB, mas é documentado em detalhes para usuários curiosos. Fazemos referência ao item de exemplo compartilhado anteriormente neste documento:
Considere estes dois itens de exemplo:
[
{
"id": 1,
"locations": [
{ "country": "Germany", "city": "Berlin" },
{ "country": "France", "city": "Paris" }
],
"headquarters": { "country": "Belgium", "employees": 250 },
"exports": [
{ "city": "Moscow" },
{ "city": "Athens" }
]
},
{
"id": 2,
"locations": [
{ "country": "Ireland", "city": "Dublin" }
],
"headquarters": { "country": "Belgium", "employees": 200 },
"exports": [
{ "city": "Moscow" },
{ "city": "Athens" },
{ "city": "London" }
]
}
]
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 de item é representado em muitas páginas de índice diferentes para o contêiner. Aqui está um diagrama de exemplo de um índice invertido para um contêiner que inclui os dois itens de exemplo:
| Caminho | Valor | Lista de identificadores de itens |
|---|---|---|
/locations/0/country |
Germany |
[1] |
/locations/0/country |
Ireland |
[2] |
/locations/0/city |
Berlin |
[1] |
/locations/0/city |
Dublin |
[2] |
/locations/1/country |
France |
[1] |
/locations/1/city |
Paris |
[1] |
/headquarters/country |
Belgium |
[1, 2] |
/headquarters/employees |
200 |
[2] |
/headquarters/employees |
250 |
[1] |
O índice invertido tem dois atributos importantes:
Para um determinado caminho, os valores são classificados em ordem crescente. Portanto, o mecanismo de consulta pode facilmente servir
ORDER BYa partir do í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 onde há resultados.
O mecanismo de consulta pode utilizar o índice invertido de quatro maneiras diferentes:
Busca de índice
Considere a seguinte consulta:
SELECT
location
FROM
location IN company.locations
WHERE
location.country = 'France'
O predicado de consulta (filtragem em itens em que qualquer local tem "França" como sua região) corresponderia ao caminho descrito aqui:
locations1-
country:France
-
O diagrama de árvore mostra um nó raiz com três ramos: "locais", "quartel-general" e "exportações". "Localizações" divide-se em dois nós numerados, cada um com dois subnós relacionados com a localização ("Alemanha/Berlim" e "França/Paris"). "Sede" tem "Bélgica" para sua localização e "funcionários" ("250"). As "Exportações" dividem-se em dois nós numerados, cada um com um subnó "cidade" ("Moscovo" e "Atenas"). Os caminhos para "locais", "1", "localizações" e "França" são destacados.
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 o Item 1. 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 do índice e a carga de RU da pesquisa do índice são incrivelmente baixos, independentemente do volume total de dados.
Varredura precisa do índice
Considere a seguinte consulta:
SELECT
*
FROM
company
WHERE
company.headquarters.employees > 200
O predicado de consulta (filtrando itens com mais de 200 funcionários) pode ser avaliado com uma varredura precisa do índice no caminho headquarters/employees. Ao realizar uma verificação de índice precisa, o mecanismo de consulta começa fazendo uma pesquisa binária do conjunto distinto e possível de valores para localizar o valor 200 no caminho headquarters/employees. Como os valores de cada caminho são classificados em ordem crescente, é fácil para o mecanismo de consulta fazer uma pesquisa binária. Depois que o mecanismo de consulta encontrar o valor 200, ele começa a ler todas as páginas de índice restantes (indo na direção crescente).
Como o mecanismo de consulta pode fazer uma pesquisa binária para evitar a varredura de páginas de índice desnecessárias, varreduras de índice precisas tendem a ter latência comparável e encargos de RU para operações de busca de índice.
Verificação de índice expandida
Considere a seguinte consulta:
SELECT
*
FROM
company
WHERE
STARTSWITH(company.headquarters.country, "United", true)
O predicado de consulta (filtragem de itens que têm sede num local cujo nome começa com "United", não diferenciando maiúsculas de minúsculas) pode ser avaliado através de um escaneamento expandido do índice no caminho headquarters/country. As operações que fazem uma verificação de índice expandida têm otimizações que podem ajudar a evitar a necessidade de verificar todas as páginas de índice, mas são um pouco mais caras do que a pesquisa binária de uma varredura de índice precisa.
Por exemplo, ao avaliar a condição de insensibilidade a maiúsculas e minúsculas em StartsWith, o mecanismo de consulta verifica o índice para várias combinações de valores em maiúsculas e minúsculas. Essa otimização permite que o mecanismo de consulta evite a leitura da 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, por isso são amplamente categorizadas como verificação de índice expandida.
Verificação completa do índice
Considere a seguinte consulta:
SELECT
*
FROM
company
WHERE
CONTAINS(company.headquarters.country, "United")
O predicado de consulta (filtragem em itens que têm sede num local que contém "United") pode ser avaliado com uma verificação de índice no caminho headquarters/country. Ao contrário de uma verificação de índice precisa, uma verificação de índice completa sempre examina o conjunto distinto de valores possíveis para identificar as páginas de índice onde há resultados. Neste caso, CONTAINS é executado no índice. O tempo de pesquisa do índice e a cobrança de RU para pesquisas de índice aumentam à medida que a cardinalidade do caminho aumenta. Em outras palavras, quanto mais valores distintos possíveis que o mecanismo de consulta precisa verificar, maior a latência e a carga de RU envolvidas na execução de uma verificação de índice completa.
Por exemplo, considere duas propriedades: town e country. A cardinalidade da cidade é de 5.000 e a cardinalidade de country é de 200. Aqui estão dois exemplos de consultas, cada um com uma CONTAINS função do sistema que realiza uma análise completa do índice na town propriedade. A primeira consulta usa mais unidades de solicitação (RUs) do que a segunda consulta porque a cardinalidade da cidade é maior do que country.
SELECT
*
FROM
container c
WHERE
CONTAINS(c.town, "Red", false)
SELECT
*
FROM
c
WHERE
CONTAINS(c.country, "States", false)
Análise 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 repositório transacional para avaliar o filtro de consulta. As análises completas não utilizam o índice e têm uma carga 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 pesquisa vetorial sem um índice vetorial definido
Se você não definir uma política de índice de vetor e usar a VECTORDISTANCE função de sistema em uma ORDER BY cláusula, essa consulta resultará em uma verificação completa e terá uma cobrança de RU maior do que se você definisse uma política de índice de vetor. Similaridade, se você usar VECTORDISTANCE com o valor booleano 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, considerávamos apenas 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 seguinte consulta:
SELECT
*
FROM
company
WHERE
company.headquarters.employees = 200 AND CONTAINS(company.headquarters.country, "United")
Para executar esta consulta, o mecanismo de consulta deve realizar uma busca de índice em headquarters/employees e uma verificação completa de índice em headquarters/country. O mecanismo de consulta tem heurísticas internas que ele usa para avaliar a expressão do 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 fazendo a busca de índice primeiro. Se, por exemplo, apenas 50 itens correspondessem ao filtro de igualdade, o mecanismo de consulta só precisaria avaliar CONTAINS nas páginas de índice que continham esses 50 itens. Uma varredura de índice completa de todo o contêiner não seria necessária.
Utilização de índice para funções de agregado escalar
As consultas com funções agregadas 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, o carregamento de correspondências de índice falso positivo não tem nenhum efeito percetível na utilização do índice.
Por exemplo, considere a consulta seguinte:
SELECT
*
FROM
company
WHERE
CONTAINS(company.headquarters.country, "United")
A CONTAINS função do sistema pode retornar alguns resultados de falsos positivos, portanto, o mecanismo de consulta precisa verificar se cada item lá existente corresponde à expressão de filtro. Neste exemplo, o mecanismo de consulta pode precisar apenas carregar alguns itens extras, portanto, o efeito na utilização do índice e na carga de RU é mínimo.
No entanto, consultas com funções agregadas devem depender exclusivamente do índice para usá-lo. Por exemplo, considere a seguinte consulta com uma COUNT agregação:
SELECT
COUNT(1)
FROM
company
WHERE
CONTAINS(company.headquarters.country, "United")
Como no primeiro exemplo, a função do CONTAINS sistema pode retornar algumas correspondências de falsos positivos. Ao contrário da SELECT * consulta, no entanto, a COUNT consulta 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, por isso, se houver uma chance de uma expressão de filtro retornar correspondências de falsos positivos, o mecanismo de consulta fará um rastreio completo.
As consultas com as seguintes funções agregadas devem depender exclusivamente do índice, portanto, avaliar algumas funções do sistema requer uma verificação completa.