Como acelerei um relatório em 150x
Trabalhando no Governo do Estado de Roraima eu tenho que lidar com relatórios frequentemente, seja para criar algum tipo de dashboard ou para modificar como os dados são processados/apresentados.
Dado esse contexto, existia um relatório específico que demorava MUITO TEMPO para ser gerado e que me deixava insano. Ele tinha esses agravantes:
Gerar esse relatório para os 25 meses demorava cerca de 15 minutos. Você pode pensar que isso não é muito, mas esse trabalho era realizado toda vez que alguém acessava uma o dashboard, e até os dados serem mostrados, o usuário passava 15 minutos olhando para uma tela de carregamento.
Eu percebi que isso era inviável, e tomei alguns passos para melhorar o desempenho.
1. Reduzir número de colunas solicitadas no SQL
Normalmente, esse relatório tem um script SQL gigantesco, definido para um sistema maior utilizado pelo Estado. No entanto, eu não precisava da maioria dos dados que retornavam dele, e o que sobrava apenas tornava as requisições mais lentas. Então, o meu primeiro passo foi remover todas as colunas desnecessárias do SQL, como exemplificado abaixo.
Antes:
SELECT A,
COLUNA_DESNECESSARIA_B,
COLUNA_DESNECESSARIA_C,
...,
FROM TABELA_A,
TABELA_COM_JOIN_DESNECESSARIA_B,
SUB_QUERY_LENTA_C,
...
Depois:
SELECT A,
D
FROM TABELA_A,
SUB_QUERY_LENTA_D
Essa mudança foi uma das mais cruciais em termos de performance. O total de colunas solicitadas foi de 30+ para 2, o que reduziu o tempo para consultar os relatórios de 15 minutos para 2 minutos.
Os ganhos em performance foram de 85%.
Recomendados pelo LinkedIn
2. Usar consultas simultâneas
Mesmo reduzindo o tempo de consulta dos relatório para 2 minutos, ainda demorava muito para que eles fossem chamados um por um. Por que não consultar todos ao mesmo tempo?
A solução para isso foi relativamente simples: utilizar as múltiplas threads disponíveis no servidor a meu favor e consultar os 25 relatórios concorrentemente. Dessa forma, reduzi o tempo de consulta de 2 minutos para cerca de 30 segundos.
Os ganhos em performance foram de 75%.
3. Utilizando cache
Procurando por padrões nos relatórios para deixá-los mais performáticos, notei que os dados dos relatórios de 2 meses atrás ou antes não sofriam alterações frequentes.
Sabendo disso, implementei um sistema de cache para qualquer relatório que fosse de pelo menos 2 meses atrás. Essa modificação foi super eficaz, deixando qualquer consulta a relatórios mais antigos extremamente rápida (menos de 1 segundo). Isso reduziu o tempo de 30 segundos para 6 segundos.
Os ganhos em performance foram de 80%.
Conclusão
De 15 minutos a 6 segundos, o ganho de performance foi de 150 vezes. Ainda não é a melhor experiência de todas para o usuário, mas já é bem melhor do que esperar enquanto reclama do sistema rsrs.
O desenvolvimento desse dashboard me deu vários insights em questões de performance e experiência do usuário, e montar ele foi extremamente recompensador. O objetivo agora é reduzir ainda mais o tempo para relatórios mais atuais e refatorar o código para deixar ele mais manutenível.
Me desejem sorte 😁.
PS: Eu acredito que mexendo no script SQL vou acabar achando uma forma de puxar o relatório de 24 meses direto, e eu espero que isso deixe ele mais rápido também.
DevOps | Docker | Automação de Data Centers | Redes e Desenvolvimento em Python
8 mMuito boa a solução de otimização eu acredito que você poderia otimizar ainda mais a eficiência das requisições e mitigar possíveis sobrecargas na rede, considerando o uso de funções internas do banco de dados em vez de consultas externas. Isso permite aproveitar a otimização interna do banco de dados, resultando em um processamento mais rápido e eficaz dos dados, além de minimizar a latência e possíveis falhas de conexão associadas às consultas externas.