Arquitetura de referência: data warehouse / analytics
Consultas analíticas (relatórios, agregações, scans amplos) são fundamentalmente diferentes das transações OLTP: poucas, mas muito amplas e longas. A partir da decisão de separar o analytics do OLTP, esta árvore percorre passo a passo componentes como o método de carga (ETL vs ELT), armazenamento colunar/columnstore, modelagem em star schema, particionamento + compressão e pré-cálculo com materialized views, ponderando o trade-off entre concorrência e throughput.
Sua carga analítica roda no mesmo banco que o OLTP?
O erro mais comum é executar relatórios pesados no banco transacional de produção e degradar a latência do OLTP. A primeira decisão é a separação: o analytics ainda roda na instância OLTP, você está montando um ambiente analítico separado, ou está decidindo como levar os dados até lá?
- Os relatórios ainda rodam no OLTP de produção; eles deixam o OLTP lento
- Já existe um warehouse separado; como devo carregar os dados?
- Já existe um warehouse; as consultas continuam lentas, como devo modelar?
Onde você vai transformar: antes ou depois da carga?
Ao mover dados das origens para o warehouse, você fará a limpeza/transformação em uma camada de processamento separada antes da carga (ETL), ou carregará primeiro os dados brutos no warehouse e os transformará com SQL dentro do poderoso engine do warehouse (ELT)? A decisão depende do poder de processamento do warehouse e da necessidade de flexibilidade de schema.
- A transformação é complexa/externa; faça-a antes da carga
- O warehouse é poderoso; carregue bruto e transforme dentro com SQL
O gargalo das consultas está no layout de armazenamento ou no modelo de dados?
Se o analytics está lento, há duas alavancas principais. Scans amplos leem a linha inteira no armazenamento por linhas; o armazenamento colunar lê apenas as colunas necessárias e comprime bem. Do lado do modelo, a normalização excessiva significa muitos joins que deixam as consultas lentas; um star schema (fato + dimensão) simplifica as coisas para analytics.
- Scans amplos de agregação estão lentos; poucas colunas são lidas
- Joins demais, schema normalizado complexo
- O mesmo relatório pesado produz o mesmo resultado repetidamente
Recomendação: separe o analytics do OLTP
Cargas transacionais e analíticas se sufocam mutuamente no mesmo engine: relatórios longos seguram locks/IO e atrasam as transações curtas. Mover o analytics para um destino separado (uma read replica ou um warehouse analítico separado) alivia os dois lados.
Recomendação: ETL (transformar antes da carga)
No ETL, os dados são extraídos das origens (Extract), limpos e transformados em uma camada de processamento separada (Transform) e só então carregados no warehouse (Load). Somente dados limpos e conformes ao modelo entram no warehouse.
Recomendação: ELT (transformar dentro do warehouse)
No ELT, os dados brutos são carregados primeiro no warehouse e a transformação acontece dentro do próprio engine SQL poderoso do warehouse. Como os warehouses colunares modernos têm alto poder de processamento, você move os dados uma vez e os processa lá dentro, em vez de levar a transformação até os dados.
Recomendação: armazenamento colunar / columnstore + compressão
Consultas analíticas normalmente varrem poucas colunas em todas as linhas. O armazenamento colunar guarda os dados coluna por coluna; lê apenas as colunas necessárias, comprime muito bem porque valores semelhantes ficam lado a lado, e o IO cai drasticamente.
Recomendação: star schema (fato + dimensão)
Em um modelo analítico, uma tabela de fatos com as medidas fica no centro, cercada por tabelas de dimensão descritivas. Em comparação com um schema excessivamente normalizado, o número de joins diminui, as consultas ficam mais simples e o engine gera planos melhores.
Recomendação: pré-cálculo com materialized views
Se a mesma agregação pesada (receita diária, resumo mensal) é executada repetidamente e produz o mesmo resultado, armazene fisicamente o resultado em uma materialized view e faça os relatórios lerem o resultado pré-calculado. O cálculo pesado é executado uma vez e as consultas retornam instantaneamente.