Otimização do desempenho da tabela dinâmica

Este tópico aborda técnicas para otimizar o desempenho de tabelas dinâmicas, organizadas em alterações e ajustes de design.

Antes de otimizar uma tabela dinâmica, pode ser importante diagnosticar por que as atualizações estão lentas. Consulte Diagnosticar atualizações lentas para ver um fluxo de trabalho passo a passo.

Para informações sobre as categorias de desempenho, consulte Decisões de desempenho.

Mudanças no design

As mudanças de design exigem que você recrie uma tabela dinâmica, mas têm mais impacto no desempenho.

Nota

Recomendamos que você agrupe mudanças e recrie tabelas juntas em vez de fazer modificações incrementais.

Escolher um modo de atualização

O modo de atualização escolhido tem um impacto significativo no desempenho porque determina a quantidade de dados que o Snowflake processa durante cada atualização. Para informações sobre como cada modo funciona, consulte Modos de atualização de tabelas dinâmicas.

Importante

As tabelas dinâmicas com atualização incremental não podem ser downstream em relação a tabelas dinâmicas que usam atualização completa.

Use o seguinte processo de decisão para selecionar um modo de atualização:

  1. Revise sua consulta com base na lista de construções de consulta compatíveis. Nem todos os operadores de consulta oferecem suporte à atualização incremental. Para operadores suportados, consulte Otimizar consultas para atualização incremental para entender como eles afetam o desempenho.

  2. Estime o volume de mudanças, ou seja, a porcentagem de dados que muda entre atualizações. A atualização incremental, por exemplo, funciona melhor quando menos de cinco por cento dos dados são alterados.

  3. Avalie a localidade dos dados. Verifique se suas tabelas de origem estão clusterizadas pelas chaves que você planeja usar em junções, cláusulasGROUP BY ou PARTITION BY, em sua consulta de tabela dinâmica. Se a localidade for inadequada, a eficiência da atualização incremental será reduzida. Para melhorar a localidade, consulte Melhorar a localidade de dados.

  4. Escolha um modo com base na tabela a seguir:

    Modo

    Quando usar

    Incremental

    Sua consulta usa operadores compatíveis, tem menos de cinco por cento das alterações de dados entre atualizações, e as tabelas de origem têm boa localidade de dados.

    Nota

    A atualização incremental ainda pode verificar tabelas de origem, não apenas as linhas que foram alteradas. Por exemplo, uma nova linha em um lado de uma junção deve corresponder a todas as linhas na outra tabela. Até mesmo um pequeno número de mudanças pode exigir um trabalho significativo.

    Completa

    Uma grande porcentagem de alterações de dados, a consulta usa operadores não suportados ou seus dados não têm localidade.

    Automática

    Você está prototipando ou testando. Evite AUTO em contextos de produção, porque o comportamento pode mudar entre as versões do Snowflake.

  5. Ao criar uma tabela dinâmica, especifique o modo usando REFRESH_MODE = INCREMENTAL ou REFRESH_MODE = FULL na instrução CREATE DYNAMIC TABLE.

Para verificar qual modo de atualização uma tabela dinâmica usa, consulte Modo de atualização.

Otimização de consultas e pipeline

A estrutura de consultas de tabela dinâmica e pipeline afeta diretamente o desempenho da atualização. Use as diretrizes a seguir para reduzir o trabalho durante cada atualização.

Simplificar consultas individuais

  • Use junções internas em vez de junções externas. As junções internas têm um desempenho melhor com a atualização incremental. Verifique a integridade referencial em seus dados de origem para que você possa evitar junções externas.

  • Evite operações desnecessárias. Remova cláusulas DISTINCT redundantes e colunas não utilizadas. Exclua colunas largas (como grandes blobs JSON) que não são consultados com frequência.

  • Remova duplicatas de forma eficiente. Use funções de classificação em vez de DISTINCT sempre que possível.

Para orientações detalhadas sobre como SQL operadores afetam o desempenho da atualização incremental, consulte Otimizar consultas para atualização incremental.

Divisão das transformações em tabelas dinâmicas

A divisão de transformações complexas em várias tabelas dinâmicas facilita a identificação de gargalos e melhora a depuração. Com as restrições de imutabilidade, você também pode usar diferentes modos de atualização para estágios distintos.

  • Adicione filtros com antecedência. Aplique cláusulas WHERE nas tabelas dinâmicas mais próximas dos seus dados de origem para que as tabelas downstream processem menos linhas.

  • Para evitar operações DISTINCT repetidas em tabelas downstream, remova linhas duplicadas no pipeline com antecedência.

  • Reduza o número de operações por tabela. Mova junções, agregações ou funções de janela para tabelas dinâmicas intermediárias em vez de combiná-las em uma única consulta.

  • Materialize expressões compostas (como DATE_TRUNC('minute', ts)) em uma tabela intermediária antes de agrupar com base nelas. Para obter mais detalhes, consulte Otimizar agregações.

Nota

Para encontrar os pontos de divisão ideais, é necessário tentativa e erro.

Considere dividir entre operações que embaralham dados em diferentes chaves, como GROUP BY, DISTINCT, funções de janela com PARTITION BY e junções. Isso permite que cada tabela dinâmica mantenha uma localidade de dados melhor para sua operação principal. Para orientações específicas sobre o operador, consulte Otimizar consultas para atualização incremental.

O exemplo a seguir mostra como dividir uma consulta complexa em tabelas dinâmicas intermediárias.

Consulta complexa inicial:

CREATE DYNAMIC TABLE final_result
  TARGET_LAG = '1 hour'
  WAREHOUSE = my_warehouse
AS
  SELECT ...
  FROM large_table a
  JOIN dimension_table b ON ...
  JOIN another_table c ON ...
  GROUP BY ...;
Copy

Divida o pipeline complexo adicionando uma tabela dinâmica intermediária:

CREATE DYNAMIC TABLE intermediate_joined
  TARGET_LAG = DOWNSTREAM
  WAREHOUSE = my_warehouse
AS
  SELECT ...
  FROM large_table a
  JOIN dimension_table b ON ...;

CREATE DYNAMIC TABLE final_result
  TARGET_LAG = '1 hour'
  WAREHOUSE = my_warehouse
AS
  SELECT ...
  FROM intermediate_joined
  JOIN another_table c ON ...
  GROUP BY ...;
Copy

Para informações detalhadas e exemplos de como os operadores afetam o desempenho, consulte Otimizar consultas para atualização incremental.

Marcar dados históricos como imutáveis

Use a cláusula IMMUTABLE WHERE para dizer ao Snowflake que certas linhas não serão alteradas. Isso reduz o escopo de trabalho durante cada atualização.

Para sintaxe, exemplos e orientações detalhadas, consulte Uso de restrições de imutabilidade.

Ajustes

Os ajustes não exigem que você recrie tabelas dinâmicas. Você pode fazer ajustes enquanto o pipeline estiver em execução.

Ajuste da configuração do warehouse

O warehouse que você especifica na instrução CREATE DYNAMIC TABLE executa todas as atualizações para essa tabela. O tamanho e a configuração do warehouse afetam diretamente a duração e o custo da atualização.

Para mais informações sobre warehouses e tabelas dinâmicas, consulte Entender o uso do warehouse para tabelas dinâmicas. Para estratégias gerais de otimização do desempenho do warehouse, consulte Otimização de warehouses quanto ao desempenho.

Uso de um warehouse separado para inicialização

As atualizações iniciais geralmente processam significativamente mais dados do que as atualizações incrementais. Use INITIALIZATION_WAREHOUSE para executar inicializações em um warehouse maior. Reservar um warehouse menor e mais econômico para atualizações regulares:

CREATE DYNAMIC TABLE my_dynamic_table
  TARGET_LAG = 'DOWNSTREAM'
  WAREHOUSE = 'XS_WAREHOUSE'
  INITIALIZATION_WAREHOUSE = '4XL_WAREHOUSE'
  AS <query>;
Copy

Para adicionar ou alterar o warehouse de inicialização para uma tabela dinâmica existente:

ALTER DYNAMIC TABLE my_dynamic_table SET INITIALIZATION_WAREHOUSE = '4XL_WAREHOUSE';
Copy

Para remover o warehouse de inicialização e usar o warehouse primário para todas as atualizações:

ALTER DYNAMIC TABLE my_dynamic_table UNSET INITIALIZATION_WAREHOUSE;
Copy

Para visualizar a configuração do warehouse, use SHOW DYNAMIC TABLES ou verifique a função de tabela DYNAMIC_TABLE_REFRESH_HISTORY.

Redimensionar quando necessário

Para equilibrar custo e desempenho, escolha um tamanho de warehouse que evite o despejo de bytes, mas não exceda o que sua carga de trabalho pode usar em paralelo. Se for essencial que as atualizações sejam mais rápidas, aumente o tamanho um pouco além do ponto ideal de custo.

Considerações para atualizações de tabelas dinâmicas:

  • Bytes despejados: quando o histórico de consultas mostra bytes despejados para armazenamento local ou remoto, o warehouse fica sem memória durante a atualização. Um warehouse maior fornece mais memória para impedir despejos. Para obter mais detalhes, consulte Consultas grandes demais para caber na memória.

  • Atualização inicial lenta: quando a atualização inicial for lenta, considere configurar INITIALIZATION_WAREHOUSE para a criação inicial ou redimensionar temporariamente o warehouse e depois reduzi-lo após a tabela ser criada.

  • Paralelismo saturado: após um certo ponto, o paralelismo adicional proporciona cada vez menos retornos. Duplicar o tamanho do warehouse pode dobra o custo sem reduzir pela metade o tempo de execução. Para verificar como sua atualização usa o paralelismo, consulte o perfil de consultas.

Para redimensionar um warehouse, consulte Aumento do tamanho do warehouse.

Para considerações de custo, consulte Uso de crédito do warehouse virtual e Como trabalhar com warehouses.

Atualizações simultâneas com warehouses multicluster

Se várias tabelas dinâmicas compartilham um warehouse e atualizam a fila com frequência, considere usar um warehouse multicluster. Warehouses multicluster adicionam clusters automaticamente quando surge um fila de consultas e os removem quando a demanda diminui. Isso melhora a latência de atualização durante os períodos de pico sem que você precise pagar pela capacidade não utilizada durante os períodos de baixa.

Para orientações sobre como identificar e reduzir filas, consulte Redução de filas.

Warehouses multicluster exigem Enterprise Edition ou superior. Para considerações de custo, consulte Como definir a política de escalonamento para um warehouse multicluster.

Identificação do atraso correto no destino

O atraso de destino controla a frequência com que sua tabela dinâmica é atualizada. Um atraso de destino mais curto significa dados mais atualizados, mas atualizações mais frequentes e maior custo de computação. Para mais informações sobre como funciona a meta de atraso, consulte Entendendo o atraso de destino da tabela dinâmica.

Use as recomendações a seguir para otimizar o atraso de destino para sua carga de trabalho:

  • Use DOWNSTREAM para tabelas intermediárias que não precisam de garantias de atualização independentes. Essas tabelas são atualizadas somente quando as tabelas downstream precisam delas.

  • Verifique o histórico de atualizações para encontrar o atraso correto: use DYNAMIC_TABLE_REFRESH_HISTORY ou Snowsight para analisar as durações das atualizações e as atualizações ignoradas. O atraso de destino deve ser um pouco maior que a duração de atualização típica.

Alteração da meta de atraso

ALTER DYNAMIC TABLE my_dynamic_table SET TARGET_LAG = '1 hour';
Copy

Para definir uma tabela dinâmica para ser atualizada com base na demanda downstream:

ALTER DYNAMIC TABLE my_dynamic_table SET TARGET_LAG = DOWNSTREAM;
Copy

Melhorar a localidade de dados

Localidade descreve quão perto o Snowflake armazena as linhas que compartilham os mesmos valores principais. Quando as linhas com chaves correspondentes abrangem menos micropartições (boa localidade), as atualizações incrementais verificam menos dados. Quando as chaves correspondentes abrangem muitas micropartições (ou seja, a localidade é ruim), a atualização incremental pode demorar mais do que a atualização completa.

Para mais informações sobre como o Snowflake armazena dados, consulte Micropartições e clustering de dados.

Tabelas de origem do cluster

A maneira mais eficaz de melhorar a localidade é clusterizar suas tabelas de origem com base nas chaves usadas em sua consulta de tabela dinâmica (chaves JOIN, GROUP BY ou PARTITION BY):

ALTER TABLE my_source_table CLUSTER BY (join_key_column);
Copy

Quando você une várias colunas e não consegue clusterizar por todas elas:

  • Priorize o clustering de tabelas maiores pelas chaves mais seletivas.

  • Considere a criação de cópias separadas dos mesmos dados clusterizados por diferentes chaves para uso em tabelas dinâmicas distintas.

Para obter mais informações, consulte Chaves de clustering e tabelas clusterizadas. Para ativar o reclustering automático, consulte Clustering automático.

Fatores que afetam a localidade

Além do clustering da tabela de origem, dois outros fatores afetam a localidade. Eles dependem de seus padrões de dados e são mais difíceis de alterar diretamente:

  • Como os novos dados se alinham com as chaves de partição: A atualização incremental é mais rápida quando novas linhas afetam apenas uma pequena parte da tabela. Isso depende de seus padrões de ingestão de dados, não da estrutura de consulta.

    Por exemplo, dados de séries temporais agrupados por hora têm uma boa localidade porque novas linhas compartilham carimbos de data/hora recentes. Dados agrupados por uma coluna com valores distribuídos por toda a tabela têm localidade ruim.

  • Como as alterações se alinham com o clustering de tabelas dinâmicas: Quando o Snowflake aplica atualizações ou exclusões a uma tabela dinâmica, ele precisa localizar as linhas afetadas. Isso é mais rápido quando as linhas alteradas são armazenadas juntas.

    Por exemplo, as atualizações de linhas recentes têm bom desempenho quando a tabela dinâmica é ordenada naturalmente por tempo. As atualizações distribuídas por toda a tabela são mais lentas. Esse fator depende de seus padrões de carga de trabalho, incluindo quais linhas mudam e com que frequência.

Se sua localidade for ruim devido a esses fatores, considere se pode ajustar seu modelo de dados ou padrões de ingestão upstream.