Como realizei um tuning que caiu o tempo de execução de 8h para 7minutos!

     

        Fala pessoal belezura? Hoje quero mostrar para vocês como fiz para realizar um tuning mágico em um cliente aqui da consultoria, espero que gostem.



Vou mostrar a query original para vocês, claro com dados fakes e nome fake da tabela.



Essa query gera o seguinte plano:



Eu peguei a query pelo plano, então quando vi o plano já sabia que era um union com acesso a tabela 3 x, a partir desse momento fui tentar entender o que o dev queria fazer com isso.



    Vou quebrar as 3 queries do union para entendemos juntos:


Nessa primeira query ele queria simplesmente verificar quantas linhas tinham na tabela com o filtro de da data "maior", pegando também a maior data de carga, o resto ele coloca como 0 para que ele some tudo na CTE e fique com uma linha só.





Depois ele faz a mesma lógica para pegar as linhas que são maiores que 7 dias, considerando a data de hoje:






Por último ele faz isso para a tabela 


Depois ele junta tudo isso em uma agregação na sub query:


Legal, agora que entendemos o que ele quer, o que eu de cara pensei ai ao ver essa query "Será que posso acessar essa tabela 1 ou no máximo 2 vezes?"

Ao pensar nisso, olhei mais de perto dois filtros, os filtros abaixo:

Esse 

E esse



E pensei  "Ora o filtro número 2 não satisfaz essas duas condições?" Sim, satisfaz, pq no primeiro filtro ele queria pegar tudo que for maior que a data que hoje e no segundo ele quer pegar tudo que for maior que os últimos 7 dias, sendo assim, também pegaria o dia de amanha, MASSSSS ainda tinha um problema para resolver, como iria separar esse count() ? Dai me lembrei de uma dica que o  Marcio da Dataside me deu e pensei, acho que posso usar aqui :)

 Então fiz a seguinte reescrita:



Eu "simplesmente" coloquei uma frag nas linhas que queria e somei, o que seria mais ou menos assim


Depois é só eu somar, que desse jeito eu consigo "separar" os filtros



Desse jeito, eu já eliminei dois scan na tabela, mas ainda assim, ainda precisaria pagar um scan em uma tabela de 700gb só para ver a quantidade de linhas? Foi então que me lembrei da dica da lenda do tuning  Fabiano Amorim onde eu consigo pegar o número de linhas da tabela sem precisar acessar ela :)



Eis que chego nessa reescrita final :)

Sim, eu sei que isso pode problema em casos específicos, mas o custo beneficio era muito grande, então optamos por seguir com essa reescrita



Desse jeito acessei a tabela apenas uma vez, fazendo um seek pegando apenas os últimos 7 dias em diante, UOLLLL.

Para que vocês tenham noção do ganhos, vou deixar aqui uma tabela com os números:


O profiler fica ruim para vê aqui.


Bem pessoal é isso, espero que tenham gostado e que ajude algum de vocês ai.

Comentários

Postar um comentário

Postagens mais visitadas deste blog

Tuning no Postgres utlizando View Materializada

Window Functions: Row_number()