Data Become

logo data become

Z-Order: Otimizando consultas no Delta Lake

Introdução

O Delta Lake é uma camada de armazenamento para tabelas ACID acima da camada de armazenamento de objetos ou Data Lake. Esta camada adiciona um universo de novas funcionalidades para manipulação, gestão e otimização do Data Lake.

Neste artigo você vai entender melhor como o Delta Lake, de forma automática, otimiza suas tabelas bem como podemos de forma explícita melhorar a performance de nossas consultas utilizando os comandos OPTIMIZE e Z-ORDER.

Layout Otimizado dos Dados

A camada Delta aplica uma série de otimizações em suas tabelas, de forma a garantir:

  • Maior confiabilidade nos conjunto de dados por impor a aplicação de um schema
  • Log transacional: Onde podemos acompanhar e auditar diferentes versões da nossa tabela.
  • Transacionalidade: As transações são realizadas de forma ACID, o que possibilita o suporte a transações como UPSERT, DELETE e MERGE.
  • Performance: Através de otimizações de compactação e data skipping. 

Sabemos que tabelas Delta são armazenadas utilizando objetos do Apache Parquet, um formato de arquivo orientado a colunas e com integrações aprimoradas para motores como o Apache Spark e outras ferramentas no ambiente de big data. 

Por padrão, um arquivo Parquet armazena em seu rodapé algumas estatísticas sobre cada coluna, como valores mínimos e máximos. Estas estatísticas permitem que os sistemas de processamento evitem ler seções desnecessárias do arquivo, tornando o processo de leitura muito mais rápido e eficiente. Este processo é conhecido como “Data Skipping” ou salto de dados. 

O Data Skipping é uma técnica usada para pular blocos de dados irrelevantes para uma consulta específica, trata-se de uma técnica muito eficiente para melhor o desempenho de consultas em grandes conjuntos de dados.

O Data Skipping no Delta Lake é semelhante ao data skipping em arquivos Parquet, mas é ainda mais eficiente porque aproveita ao máximo o conhecimento sobre a estrutura de dados e o esquema da tabela. Ele também usa índices estatísticos avançados que são armazenados como metadados em um arquivo Delta Lake, para identificar quais seções de dados precisam ser lidas para responder a uma consulta.

Estes índices estatísticos são coletados automaticamente quando você escreve dados em uma tabela Delta. No Databricks você não precisa configurar esta opção, esta feature é ativada por padrão, entretanto a sua efetividade depende do layout dos seus dados. 

Por padrão, no Databricks, o Delta Lake coleta estatísticas sobre as 32 primeiras colunas definidas no schema de sua tabela. Você até pode alterar a configuração padrão para considerar um número maior de colunas mas esteja ciente que quanto mais colunas maior o custo computacional.

Indices otimizados para o Z-Ordering

Para uma melhor performance em suas consultas você pode, de forma explícita, utilizar o comando Z-Order para indicar adicionalmente quais são os campos/colunas chave dentro de sua tabela para a realização de um data skipping. 

Se você possui em seu conjunto de dados uma coluna que é utilizada com grande frequência como filtro em suas consultas, então poderá considerá-la como índice para o Z-Order. 

Por exemplo: Você talvez possua na sua base de dados de vendas um campo relativo à “data da venda”, e na grande maioria de suas consultas costuma-se utilizar este campo como filtro. 

Um campo é forte candidato para o Z-Order quando:

  1. É um campo chave utilizando com frequência
  2. Quando o campo possui alta cardinalidade, ou seja, uma série de diferentes classes. O campo gênero (Masculino ou Feminino) é um exemplo de campo a não ser utilizado pois possui baixa cardinalidade já que só assume poucos valores.
  3. Se sua tabela for particionada, o campo não pode ser o mesmo que o utilizado para particionamento.

Considere utilizar um número pequeno de colunas para o Z-Order, quanto mais colunas maior será o tempo de processamento para execução do comando.

Dependendo do seu caso pode não ser necessário particionar sua tabela, talvez somente o Z-Order já lhe traga a performance esperada. Para saber mais sobre particionamento de tabelas preparamos um outro artigo aqui no nosso blog.

O comando Z-Order

O comando ZORDER é utilizado em conjunto com o comando OPTIMIZE. O comando OPTIMIZE veio para aprimorar a tratativa de um dos problemas principais no armazenamento de dados em arquivos distribuídos, o problema dos “Small Files”. 

Em outro artigo aqui no nosso blog falamos mais sobre Small Files e como a camada Delta Lake otimiza e resolve este problema. 

Resumidamente, o comando OPTIMIZE procura por “pequenos pedaços” do seu conjunto de dados tentando agrupá-los em um arquivos maiores, diminuindo então a quantidade de arquivos necessários para manter seus dados.

A sintaxe para execução do Z-order então fica :

SQL
%sql

OPTIMIZE vendas 
  ZORDER BY(produto_categoria); 

-- Se você deseja otimizar somente uma parte do conjunto, utilize o WHERE
OPTIMIZE vendas WHERE data_venda >= "2023-01-01" AND produto_categorias = "Eletrodomesticos" 
  ZORDER BY(produto_categoria);
  
  
    

Python
%python

from delta.tables import DeltaTable

deltaTable = DeltaTable.forPath(spark, pathToTable) # pathToTable = caminho/location da tabela

vendas = deltaTable

vendas.optimize().executeZOrderBy(produto_categoria)

# Se você deseja otimizar somente uma parte do conjunto, utilize o WHERE
vendas.optimize() \
      .where("data_venda >= '2023-01-01' AND produto_categorias = 'Eletrodomesticos'") \
      .executeZOrderBy(produto_categorias)


Conclusão

Apesar de aplicar automaticamente uma série de otimizações na forma como os dados são armazenados e gerenciados a camada Delta Lake ainda nos permite adicionar uma série de parametrizações, específicas para o nosso problema de forma a obter a melhor performance possível.

referências: Databricks: Delta Lake Data Skipping

Leave a Comment

O seu endereço de email não será publicado. Campos obrigatórios marcados com *

Scroll to Top