Um causo de 2016 sobre dados
Uma experiência com dashboards, SQL e CRM que anos depois ajuda a enxergar melhor OLTP, OLAP, modelagem e arquitetura analítica.
Durante um estágio, precisei montar alguns dashboards para um sistema web, em um cenário de CRM. Usávamos MySQL, então recorri ao SQL para buscar os dados necessários e depois colocá-los nos gráficos.
Só que havia uma parte que me dava bastante trabalho: como transformar aqueles dados em uma informação que realmente fizesse sentido? Eu conseguia consultar o banco, mas ainda tinha dificuldade para decidir qual gráfico usar, o que comparar e até mesmo como interpretar alguns daqueles dados.
Na época, eu ainda não tinha muita familiaridade com conceitos como dados qualitativos e quantitativos, nominais, ordinais, discretos e contínuos. Lendo sobre isso hoje, consigo olhar para aquela situação de outra forma: o SQL me ajudava a buscar os dados, mas isso era só uma parte do problema. Eu também precisava entender que tipo de dado estava olhando e qual história aqueles dados poderiam contar.
Mas deu tudo certo no final. Consegui entregar o dashboard, depois de algumas idas e vindas porque ele não passava no crivo do QA. Só que, olhando para aquela experiência hoje, sei que entregar não significa necessariamente ter encontrado a melhor solução.
Para conseguir filtrar e preparar os dados que precisava, acabei criando consultas SQL bastante grandes. Na época, eu ainda não tinha a visão que tenho hoje sobre modelagem de dados, normalização, desnormalização e, principalmente, sobre a diferença entre um modelo pensado para transações (OLTP) e outro pensado para análises (OLAP).
E é justamente aí que essa história fica interessante. O sistema precisava continuar realizando suas operações normais: cadastrar informações, atualizar registros, relacionar entidades e atender às requisições da aplicação. Ao mesmo tempo, os dashboards precisavam fazer consultas complexas, agregações, filtros e análises sobre grandes volumes de dados.
Ou seja, duas necessidades bastante diferentes estavam disputando os mesmos recursos. Já enfrentei problemas de performance justamente por não separar corretamente essas responsabilidades. O resultado foi a execução de relatórios com consultas complexas competindo diretamente por recursos com processos transacionais.
Essas consultas analíticas aumentavam o consumo de CPU, I/O e memória, afetando inclusive operações rotineiras do sistema. Em alguns cenários, elas acessavam grandes volumes de dados históricos que já não sofriam atualizações, mas ainda assim continuavam impactando o ambiente transacional.
E aqui existe uma distinção que demorei alguns anos para enxergar:
O problema nem sempre está na query. Às vezes, o problema está no lugar onde aquela query está sendo executada.
Ferramentas como JasperReports podem ajudar bastante na camada de relatórios, otimizando paginação, renderização e permitindo recursos como cache e agendamento. Mas isso não elimina o custo estrutural de uma consulta pesada executada sobre um modelo altamente normalizado e orientado para transações.
Se a base não estiver preparada para leitura analítica, o banco continuará assumindo esse custo. Quando não é possível utilizar um banco separado para a camada analítica, existem outras alternativas: tabelas desnormalizadas, modelos específicos de leitura, snapshots e materialized views podem reduzir a complexidade das consultas e ajudar a preservar a estabilidade do ambiente transacional.
E, quando o volume ou a necessidade de análise cresce ainda mais, começa a fazer sentido pensar em uma arquitetura onde a camada analítica tenha seus próprios recursos. É justamente nesse contexto que tecnologias e conceitos como data warehouse, bancos colunares e OLAP começam a fazer mais sentido.
Hoje, por exemplo, estou testando o ClickHouse e tentando entender onde uma solução desse tipo poderia se encaixar em alguns cenários. O mais interessante é perceber que o problema que eu enfrentava em 2016 não desapareceu. Eu apenas passei a enxergá-lo com outras ferramentas e conhecimentos.
Naquela época, eu queria fazer o dashboard funcionar. Hoje, penso também em:
- Como esses dados serão consumidos?
- Qual modelo é adequado para essa leitura?
- Essa consulta vai competir com as operações transacionais?
- Preciso realmente consultar os dados diretamente da base OLTP?
- Seria melhor preparar uma camada específica para análise?
Essa experiência me ensinou, mesmo que eu ainda não soubesse disso naquela época, que relatórios eficientes não nascem apenas de SQL otimizado. Eles começam na forma como pensamos os dados, o modelo de leitura e a arquitetura que existe por trás deles.
É curioso como algumas dificuldades que tivemos no começo da carreira só fazem sentido muitos anos depois.
Vivendo e aprendendo. Caindo e levantando.