Melhores práticas para consultas de Linguagem de Pesquisa Kusto

Seguem-se várias melhores práticas a seguir para tornar a sua consulta mais rápida.

Resumindo

Ação Utilização Não utilizar Notas
Reduzir a quantidade de dados que estão a ser consultados Utilize mecanismos como o where operador para reduzir a quantidade de dados que estão a ser processados. Veja abaixo as formas eficientes de reduzir a quantidade de dados que estão a ser processados.
Evitar utilizar referências qualificadas redundantes Ao referenciar entidades locais, utilize o nome não qualificado. Veja abaixo para obter mais informações sobre o assunto.
datetime colunas Utilize o datetime tipo de dados. Não utilize o long tipo de dados. Nas consultas, não utilize funções de conversão de tempo unix, como unixtime_milliseconds_todatetime(). Em vez disso, utilize políticas de atualização para converter o tempo unix para o datetime tipo de dados durante a ingestão.
Operadores de cadeias Utilizar o has operador Não utilizar contains Ao procurar tokens completos, has funciona melhor, uma vez que não procura subcadeias.
Operadores sensíveis a maiúsculas e minúsculas Utilizar o comando == Não utilizar =~ Utilize operadores sensíveis a maiúsculas e minúsculas sempre que possível.
Utilizar o comando in Não utilizar in~
Utilizar o comando contains_cs Não utilizar contains Se puder utilizar has/has_cs e não utilizar contains/contains_cs, é ainda melhor.
Procurar texto Procurar numa coluna específica Não utilizar * * efetua uma pesquisa em texto completo em todas as colunas.
Extrair campos de objetos dinâmicos em milhões de linhas Materialize a coluna no momento da ingestão se a maioria das consultas extrair campos de objetos dinâmicos em milhões de linhas. Desta forma, só pagará uma vez pela extração de colunas.
Procurar chaves/valores raros em objetos dinâmicos Utilizar o comando MyTable | where DynamicColumn has "Rare value" | where DynamicColumn.SomeKey == "Rare value" Não utilizar MyTable | where DynamicColumn.SomeKey == "Rare value" Desta forma, filtra a maioria dos registos e faz a análise JSON apenas dos restantes.
let instrução com um valor que utiliza mais do que uma vez Utilizar a função materialize() Para obter mais informações sobre como utilizar materialize()o , consulte materializar(). Para obter mais informações, veja Otimizar consultas que utilizam expressões nomeadas.
Aplicar conversões em mais de mil milhões de registos Reformate a consulta para reduzir a quantidade de dados inseridos na conversão. Não converta grandes quantidades de dados se for possível evitá-los.
Novas consultas Utilize limit [small number] ou count no final. A execução de consultas desvinculadas em conjuntos de dados desconhecidos pode resultar na devolução de GBs de resultados ao cliente, o que resulta numa resposta lenta e num cluster ocupado.
Comparações não sensíveis a maiúsculas e minúsculas Utilizar o comando Col =~ "lowercasestring" Não utilizar tolower(Col) == "lowercasestring"
Comparar dados já em minúsculas (ou em maiúsculas) Col == "lowercasestring" (ou Col == "UPPERCASESTRING") Evite utilizar comparações não sensíveis a maiúsculas e minúsculas.
Filtrar em colunas Filtrar numa coluna de tabela. Não filtre numa coluna calculada.
Utilizar o comando T | where predicate(*Expression*) Não utilizar T | extend _value = *Expression* | where predicate(_value)
operador summarize Utilize hint.shufflekey=<key> quando o group by keys operador de resumo estiver com cardinalidade elevada. A cardinalidade elevada é idealmente superior a 1 milhão.
operador join Selecione a tabela com menos linhas para ser a primeira (mais à esquerda na consulta).
Utilize in em vez da semi esquerda join para filtrar por uma única coluna.
Associar entre clusters Nos clusters, execute a consulta no lado "direito" da associação, onde está localizada a maioria dos dados.
Associar quando o lado esquerdo é pequeno e o lado direito é grande Utilizar hint.strategy=broadcast Pequeno refere-se a até 100 MB de dados.
Associar quando o lado direito é pequeno e o lado esquerdo é grande Utilizar o operador de pesquisa em vez do join operador Se o lado direito da pesquisa for maior do que várias dezenas de MBs, a consulta falhará.
Associar quando ambos os lados são demasiado grandes Utilizar hint.shufflekey=<key> Utilize quando a chave de associação tiver uma cardinalidade elevada.
Extrair valores na coluna com cadeias que partilham o mesmo formato ou padrão Utilizar o operador de análise Não utilize várias extract() instruções. Por exemplo, valores como "Time = <time>, ResourceId = <resourceId>, Duration = <duration>, ...."
função extract() Utilize quando as cadeias analisadas não seguem todos o mesmo formato ou padrão. Extraia os valores necessários com um REGEX.
materializar() função Envie todos os operadores possíveis que reduzam o conjunto de dados materializado e continuem a manter a semântica da consulta. Por exemplo, filtros ou apenas colunas necessárias para o projeto. Para obter mais informações, veja Otimizar consultas que utilizam expressões nomeadas.
Utilizar vistas materializadas Utilize vistas materializadas para armazenar agregações utilizadas frequentemente. Preferir utilizar a materialized_view() função para consultar apenas parte materializada materialized_view('MV')

Reduzir a quantidade de dados que estão a ser processados

O desempenho de uma consulta depende diretamente da quantidade de dados que precisa de processar. Quanto menos dados forem processados, mais rápida será a consulta (e menos recursos consumirá). Por conseguinte, a melhor prática mais importante é estruturar a consulta de forma a reduzir a quantidade de dados que estão a ser processados.

Nota

No debate abaixo, é importante ter em conta o conceito de seletividade de filtros. Selectivity é a percentagem de registos que são filtrados ao filtrar por algum predicado. Um predicado altamente seletivo significa que apenas alguns registos permanecem após a aplicação do predicado, reduzindo a quantidade de dados que precisam de ser processados de forma eficaz.

Por ordem de importância:

  • Apenas tabelas de referência cujos dados são necessários para a consulta. Por exemplo, ao utilizar o union operador com referências de tabela de carateres universais, é melhor do ponto de vista de desempenho referenciar apenas algumas tabelas, em vez de utilizar um caráter universal (*) para referenciar todas as tabelas e, em seguida, filtrar os dados com um predicado no nome da tabela de origem.

  • Tire partido do âmbito de dados de uma tabela se a consulta for relevante apenas para um âmbito específico. A função table() fornece uma forma eficiente de eliminar os dados ao escopiá-lo de acordo com a política de colocação em cache (o parâmetro DataScope ).

  • Aplique o where operador de consulta imediatamente a seguir às referências da tabela.

  • Ao utilizar o where operador de consulta, uma utilização criteriosa da ordem dos predicados (num único operador ou com vários operadores consecutivos, não importa qual) pode ter um efeito significativo no desempenho da consulta, conforme explicado abaixo.

  • Aplique primeiro predicados de partições horizontais. Isto significa que os predicados que utilizam a função extent_id() devem ser aplicados primeiro, assim como predicados que utilizam a função extent_tags() e predicados que são muito seletivos sobre as partições de dados da tabela (se definidas).

  • Em seguida, aplique predicados que atuam sobre datetime colunas de tabela. O Kusto inclui um índice muito eficiente nessas colunas, eliminando frequentemente partições horizontais de dados completas sem ter de aceder a essas partições horizontais.

  • Em seguida, aplique predicados que atuem string sobre e dynamic colunas, especialmente esses predicados que se aplicam ao nível do termo. Os predicados devem ser ordenados pela seletividade (por exemplo, procurar um ID de utilizador quando há milhões de utilizadores é muito seletivo e normalmente é uma pesquisa de termos para a qual o índice é muito eficiente.)

  • Em seguida, aplique predicados que sejam seletivos e baseados em colunas numéricas.

  • Por último, para consultas que analisam os dados de uma coluna de tabela (por exemplo, para predicados como "contém "@!@!" que não têm termos e não beneficiam da indexação), ordene os predicados de modo a que os que analisam colunas com menos dados sejam os primeiros. Isto reduz a necessidade de descomprimir e analisar colunas grandes.

Evitar utilizar referências qualificadas redundantes

As entidades, como tabelas e vistas materializadas, são referenciadas pelo nome. Por exemplo, a tabela T pode ser referenciada como simples T (o nome não qualificado ) ou através de um qualificador de base de dados (por exemplo, database("DB").T quando a tabela está numa base de dados denominada DB) ou utilizando um nome completamente qualificado (por exemplo cluster("X.Y.kusto.windows.net").database("DB").T, ).

É uma melhor prática evitar a utilização de qualificações de nomes quando são redundantes, pelos seguintes motivos:

  1. Os nomes não qualificados são mais fáceis de identificar (para um leitor humano) como pertencentes à base de dados no âmbito.

  2. Referenciar entidades de base de dados no âmbito é sempre, pelo menos, tão rápido e, em alguns casos, muito mais rápido, as entidades que pertencem a outras bases de dados (especialmente quando essas bases de dados estão num cluster diferente).) Evitar nomes qualificados ajuda o leitor a fazer a coisa certa.

Nota

Isto não quer dizer que os nomes qualificados sejam maus para o desempenho. Na verdade, o Kusto é capaz, na maioria dos casos, de identificar quando um nome completamente qualificado referencia uma entidade pertencente à base de dados no âmbito e ao "curto-circuito" da consulta para que não seja considerada uma consulta entre clusters. No entanto, recomendamos que não dependa disto quando não for necessário, pelas razões especificadas acima.