Como criar partições de tabelas em Data Warehouse: passo a passo
Este tutorial mostra como criar e gerir partições de tabelas num Data Warehouse para melhorar o desempenho de consultas, manutenção e carregamento incremental. Explica o porquê das partições e guia por um exemplo prático em SQL para partir uma tabela de factos por data.
Pré-requisitos
- Conhecimentos básicos de SQL (SELECT, CREATE TABLE, INSERT).
- Um motor de Data Warehouse que suporte particionamento (ex.: Azure Synapse, SQL Server, Snowflake, BigQuery).
- Uma tabela de factos com coluna de data (ex.: order_date).
Passo 1: Por que particionar uma tabela em Data Warehouse
Particionar divide fisicamente os dados conforme uma coluna (normalmente data). Isto reduz I/O em consultas que filtram por essa coluna, acelera a manutenção (remover dados antigos) e facilita cargas incrementais. Erros comuns incluem particionar por muitas colunas ou por cardinalidade elevada — escolher a coluna certa é crítico.
Passo 2: Escolher a estratégia de partição
Decida entre range partitioning (por intervalo de data), list partitioning ou hash partitioning. Para factos temporais, range por dia/mês/ano é o mais comum. Exemplo: particionar por month(start) permite eliminar whole partitions mensalmente, útil para retenção e arquivamento.
Passo 3: Criar uma tabela particionada (exemplo em T-SQL)
Aqui está um exemplo simples em SQL Server / Azure Synapse que usa partition function e partition scheme para criar uma tabela de factos particionada por mês na coluna order_date.
-- Criar uma function de partição por mês (valores de corte: primeiro dia de cada mês) CREATE PARTITION FUNCTION pf_OrderDate(datetime) AS RANGE RIGHT FOR VALUES ('2026-01-01','2026-02-01','2026-03-01','2026-04-01'); -- Criar um partition scheme que usa filegroups (exemplo simples com PRIMARY) CREATE PARTITION SCHEME ps_OrderDate AS PARTITION pf_OrderDate TO (PRIMARY, PRIMARY, PRIMARY, PRIMARY, PRIMARY); -- Criar tabela de factos particionada CREATE TABLE factOrders ( order_id BIGINT NOT NULL, order_date DATETIME NOT NULL, product_id INT, quantity INT, amount DECIMAL(18,2) ) ON ps_OrderDate (order_date);
Passo 4: Carregar dados em modo particionado e carga incremental
Ao carregar, direcione a carga para as partições corretas. Para cargas incrementais, insira apenas dados do período alvo. Exemplo de carga de um mês:
-- Inserir dados apenas de abril 2026 (carga incremental) INSERT INTO factOrders (order_id, order_date, product_id, quantity, amount) SELECT order_id, order_date, product_id, quantity, amount FROM stagingOrders WHERE order_date >= '2026-04-01' AND order_date < '2026-05-01';
Passo 5: Gerir retenção removendo partições antigas
Para eliminar dados antigos de forma eficiente, faça SWITCH OUT ou MERGE da partição e depois DROP. Exemplo: remover dados de janeiro 2026.
-- Criar tabela temporária com mesma estrutura e sem constraints CREATE TABLE factOrders_Archive ( order_id BIGINT NOT NULL, order_date DATETIME NOT NULL, product_id INT, quantity INT, amount DECIMAL(18,2) ); -- Mover (SWITCH) a partição de janeiro para a tabela de archive (exemplo conceptual) ALTER TABLE factOrders SWITCH PARTITION 1 TO factOrders_Archive; -- Depois pode truncar ou arquivar a tabela factOrders_Archive TRUNCATE TABLE factOrders_Archive;
Passo 6: Reorganizar e manter partições
Execute manutenção regular: rebuild/reorganize de índices por partição e actualizar estatísticas para manter o desempenho. Exemplo de rebuild para uma partição específica.
-- Rebuild do índice clustered na partição 2 (exemplo) ALTER INDEX ALL ON factOrders REBUILD PARTITION = 2;
Verificar o resultado
Confirme que as partições estão a ser usadas e que as queries filtradas por date são mais rápidas. Verifique metadados de partição e tempo de execução:
-- Listar partições e row counts (SQL Server) SELECT p.partition_number, p.rows, rng.value AS RangeBoundary FROM sys.partitions p JOIN sys.indexes i ON p.object_id = i.object_id AND p.index_id = i.index_id JOIN sys.partition_range_values rng ON rng.function_id = OBJECT_ID('pf_OrderDate') WHERE OBJECT_NAME(p.object_id) = 'factOrders'; -- Teste de desempenho: comparar tempos de query com e sem filtro por order_date SET STATISTICS TIME ON; SELECT SUM(amount) FROM factOrders WHERE order_date >= '2026-04-01' AND order_date < '2026-05-01'; SET STATISTICS TIME OFF;
Conclusão
Particionar tabelas num Data Warehouse melhora drasticamente consultas temporais e simplifica retenção. Próximos passos: testar outras estratégias (hash, list), implementar partição automática e monitorizar planos de execução. Dica: comece por uma granularidade mensal e ajuste conforme o padrão de consultas — que periodicidade faz mais sentido para os seus relatórios?