SlideShare uma empresa Scribd logo
1 de 57
Baixar para ler offline
Queries performáticas
com ORM em Python,
Django e Postgres
whatsgood.com.br
Thiago Ferreira / Python Brasil 2022
Sobre mim
🤖 Staff Software Engineer @ Routable
🐍 Pythonista
🌱 Entusiasta da cozinha (Insta: @maisumdiarioveg)
🐶 Pai de pet
🍿Mandem recomendações de filmes, séries e livros :P
Github: @thiagoferreiraw
Twitter e Medium: @tferreiraw
Linkedin: https://www.linkedin.com/in/thiago-ferreira-380427a8/
🧾 Implementando queries complexas no ORM
❌ Erros comuns nas queries (N+1)
📚 Problemas complexos além do ORM: índices
🏅Menções honrosas: Ferramentas e dicas para auxiliar na
organização e manutenção do ORM/queries
🎯 Conhecimento prático e com muitos exemplos
Sumário
Chico, boas-vindas ao time!
Sua primeira tarefa será criar
uma listagem de pedidos,
exibindo ID, Nome e total
vendido.
Tranquilo?
Modelagem do banco de dados
Listagem de pedidos
🧾 Primeira tarefa: implementar uma listagem de pedidos,
exibindo ID, Nome do cliente e total.
Hora do deploy!
🚨 Chico, os clientes estão
reclamando que a listagem de
pedidos está lenta.
Poderia verificar?
Será que o
ORM é
lento?
É lentidão do
python?
Banco
sobrecarregado?
Já estraguei o
brinquedo no
primeiro dia de
serviço 😖
1⃣ Visualizar as queries executadas
2⃣ Analisar o comando SQL gerado pelo ORM
3⃣ Otimizar de acordo com os resultados - sempre testando antes
e depois.
Identificando problemas
no ORM em 3 passos:
6 queries executadas 🚨
Por que tantas queries?
Buscando apenas orders
(sem customer)
O customer é usado ao longo do
programa, isso faz com que o
Django busque os objetos sob
demanda
Queries extras em customer
O
Uma nova query para cada iteração
da lista de orders (ids diferentes)
Queries N+1 🚨
É um problema de performance, onde para cada
iteração do laço principal (ex: Pedidos) é executada
uma nova query para buscar dados adicionais (ex:
Clientes)
Então se temos 10 pedidos na consulta, teremos 1
query para os pedidos e + 10 queries extras para trazer
os clientes
Como resolver?
Informamos ao ORM para já carregar o
customer do banco de dados
De 6 para 1 query
76%mais rápido que o anterior
SQL joins e a teoria dos conjuntos
#AgoraVai!
Comparação com SQL puro
Sem diferenças relevantes em
relação ao ORM
Melhoria de 0.6ms 😅 ~18% em relação ao ORM
otimizado. Nada muito impressionante.
🧾 Segunda tarefa: Listar um pedido com seus respectivos itens
(exibir nome do produto e categoria)
Complicando um pouco - 1-N
Muitas queries executadas (11)
Resolvendo:
De 11 para 2 queries
73%mais rápido que o anterior
Complicando MAIS: prefetch
🧾 Terceira tarefa: Listar vários pedidos com seus respectivos
itens (exibir nome do produto e categoria)
45 queries (em 5 pedidos)
Resolvendo:
-> Items já estão carregados
De 45 para 2 queries
91%mais rápido que o anterior
Select related OU prefetch related?
👉 Select Related:
- Utiliza um JOIN para trazer registros
com relação direta
Por ex:
- Order.customer
- Product.category
- Item.product
👉 Prefetch Related:
- Utiliza uma segunda query para trazer
registros relacionados (1 ou vários):
- Pode ser combinado com select related
Por ex:
- order.items
📈 Ao escrever queries com ORM, sempre considerar as
relações que serão utilizadas
🌎 SQL é nosso amigo e nos ajuda a identificar problemas
🧾 O ORM oferece vantagens sobre o SQL puro, pois não
precisamos nos preocupar com a sintaxe do SQL no nosso
código
👤Os mesmo problemas mostrados anteriormente podem
podem acontecer no Django Admin. Cuidado com o método
__str__(self)
Aprendizados com ORM
Índices no banco
de dados
📚 O que são índices?
❓ Como saber se preciso colocar um índice?
📄 Analisando o Query Plan do Postgres
🧐 Verificando se o índice é realmente usado
Chico, vi que você está
mandando muito bem na
otimização de queries, poderia
acertar essa outra página
também?
🧾 Tarefa: Otimizar uma página lenta no website. A página lista
o total vendido filtrando por email
Otimizando além do ORM
Sem problemas aparentes na
query
O que são índices?
Analisando o query plan
Analisando o query plan (visual)
From: https://tatiyants.com/pev/#/plans/new
Colocando index
Novo resultado
82%mais rápido que o anterior
Novo query plan após indexar
Novo query plan (visual)
Trade offs índices
➕ Considerar o tempo de inserção
🧐 O banco de dados pode não usar o índice
⛰ Volumetria importa
⏱ Espaço X tempo
Espaço index
Aumento de 31% no armazenamento para
contemplar o índice
Operação Problema Solução Melhoria
Listar pedidos Queries extras Select_related -76%
13.8ms -> 3.2ms
Listar um pedido
com itens
Queries extras Select_related em
ambas queries
-73%
24.2ms -> 6.4ms
Listar múltiplos
pedidos com itens
Queries extras Select_related +
prefetch_related
-91%
95.9ms -> 8.4ms
Consulta de orders
por email
Falta de índice no
campo email
Indexar o email -82%
16ms -> 2.8ms
Resultados
Managers - Organização
Managers - Organização
Signals - Código + desacoplado
Extra: Queries mais complexas
Extra: Quando as queries são
executadas?
Quando as queries são
executadas?
Querysets são “Lazy”, ou seja, não executam a query no banco de
dados antes dos dados serem necessários
Quando os dados são “necessários”?
- Ao se fazer uma iteração (for loop)
- Executar len(queryset)
- Slicing: queryset[:10]
- Listing: list(queryset)
- Calling str() and repr()
- Pickling/caching
Quando as queries são
executadas?
Ferramentas auxiliares
(em dev)
📈django-extensions:
- python manage.py shell_plus --print-sql
- python manage.py dbshell
📈 django-debug-toolbar:
- Shows a debug toolbar on the web page
📈 django-queryinspect
- Mostra estatísticas do SQL, ex:
- [SQL] 17 queries (4 duplicates), 34 ms SQL time, 243 ms
total request time
📈 Testes unitários
- self.assertNumQueries(5)
📈 django-silk
- Profilling for Django
Ferramentas auxiliares
(em prod)
Ferramentas de observabilidade e monitoramento em geral:
- Elastic APM
- New Relic
- Data Dog
- Honeycomb
- opentelemetry
Conclusão
🐢 O ORM não é lento, só pode estar mal configurado
📚 Entender como os índices funcionam e como verificá-los nos
ajuda a resolver problemas mais complexos
🛠 Existem muitas ferramentas disponíveis para auxiliar no
debug e monitoramento de queries
󰞲 Sempre testar o antes e depois de mudanças para garantir
que elas realmente são efetivas.
Projeto de exemplo
https://github.com/thiagoferreiraw/django-orm-optimization-talk
Muito Obrigado!
Bora pra discussão :)
Github: @thiagoferreiraw
Twitter e Medium: @tferreiraw
Linkedin:
https://www.linkedin.com/in/thiago-ferreira-380427a8/
Projeto de exemplo
dos slides
github.com/thiagofereriraw/django-orm-optimization-talk

Mais conteúdo relacionado

Semelhante a Python Brasil 2022 - Queries performáticas com ORM em Python, Django e Postgres.pdf

O que eu deveria saber antes de testar performance?
O que eu deveria saber antes de testar performance?O que eu deveria saber antes de testar performance?
O que eu deveria saber antes de testar performance?Ariane Izac
 
Forca de Digital & RPA
Forca de Digital & RPAForca de Digital & RPA
Forca de Digital & RPAEduardo Britto
 
TDD: A Essência do Mantra
TDD: A Essência do MantraTDD: A Essência do Mantra
TDD: A Essência do MantraDionatan default
 
In tests we trust: começando com TDD, mocks e mais
In tests we trust: começando com TDD, mocks e maisIn tests we trust: começando com TDD, mocks e mais
In tests we trust: começando com TDD, mocks e maisAna Paula Gomes
 
Big Data como Serviço: da captura à visualização de dados com alto desempenho
Big Data como Serviço: da captura à visualização de dados com alto desempenhoBig Data como Serviço: da captura à visualização de dados com alto desempenho
Big Data como Serviço: da captura à visualização de dados com alto desempenhoRicardo Longa
 
Agile Trends 2018 - Além da Automação com Machine Learning
Agile Trends 2018 - Além da Automação com Machine LearningAgile Trends 2018 - Além da Automação com Machine Learning
Agile Trends 2018 - Além da Automação com Machine LearningEmerson Bertolo
 
Qualidade de Código
Qualidade de CódigoQualidade de Código
Qualidade de CódigoJoberto Diniz
 
Slides exemplodeprocessoscrum
Slides exemplodeprocessoscrumSlides exemplodeprocessoscrum
Slides exemplodeprocessoscrumSilas Dias
 
5 dicas para estruturar seu teste de performance
5 dicas para estruturar seu teste de performance5 dicas para estruturar seu teste de performance
5 dicas para estruturar seu teste de performanceAriane Izac
 
Code Smells: o que eles dizem sobre seu código?
Code Smells: o que eles dizem sobre seu código?Code Smells: o que eles dizem sobre seu código?
Code Smells: o que eles dizem sobre seu código?Elaine Naomi
 
Programação Orientada a Aspectos
Programação Orientada a AspectosProgramação Orientada a Aspectos
Programação Orientada a AspectosRicardo Terra
 
Testes Automatizados e Especificação Por Exemplo - Unindo TI e Negócio atravé...
Testes Automatizados e Especificação Por Exemplo - Unindo TI e Negócio atravé...Testes Automatizados e Especificação Por Exemplo - Unindo TI e Negócio atravé...
Testes Automatizados e Especificação Por Exemplo - Unindo TI e Negócio atravé...Bruno Bemfica
 
Engenharia Requisitos
Engenharia RequisitosEngenharia Requisitos
Engenharia Requisitoselliando dias
 
Sistema de tarefas 1.0
Sistema de tarefas 1.0Sistema de tarefas 1.0
Sistema de tarefas 1.0Guto Xavier
 
Matando web forms e modernizando um grande varejista
Matando web forms e modernizando um grande varejistaMatando web forms e modernizando um grande varejista
Matando web forms e modernizando um grande varejistaJosé Roberto Araújo
 
TDC 2016 - Workshop sobre Planejamento Ágil de Releases
TDC 2016 - Workshop sobre Planejamento Ágil de ReleasesTDC 2016 - Workshop sobre Planejamento Ágil de Releases
TDC 2016 - Workshop sobre Planejamento Ágil de ReleasesAdriano Campestrini
 
Aumente a performance de seu site de maneira disciplinada
Aumente a performance de seu site de maneira disciplinadaAumente a performance de seu site de maneira disciplinada
Aumente a performance de seu site de maneira disciplinadaHenrique Lima
 
Day 0 iniciando na carreira em ti
Day 0   iniciando na carreira em tiDay 0   iniciando na carreira em ti
Day 0 iniciando na carreira em tiLuis Henrique Costa
 

Semelhante a Python Brasil 2022 - Queries performáticas com ORM em Python, Django e Postgres.pdf (20)

O que eu deveria saber antes de testar performance?
O que eu deveria saber antes de testar performance?O que eu deveria saber antes de testar performance?
O que eu deveria saber antes de testar performance?
 
Forca de Digital & RPA
Forca de Digital & RPAForca de Digital & RPA
Forca de Digital & RPA
 
TDD: A Essência do Mantra
TDD: A Essência do MantraTDD: A Essência do Mantra
TDD: A Essência do Mantra
 
In tests we trust: começando com TDD, mocks e mais
In tests we trust: começando com TDD, mocks e maisIn tests we trust: começando com TDD, mocks e mais
In tests we trust: começando com TDD, mocks e mais
 
Big Data como Serviço: da captura à visualização de dados com alto desempenho
Big Data como Serviço: da captura à visualização de dados com alto desempenhoBig Data como Serviço: da captura à visualização de dados com alto desempenho
Big Data como Serviço: da captura à visualização de dados com alto desempenho
 
Agile Trends 2018 - Além da Automação com Machine Learning
Agile Trends 2018 - Além da Automação com Machine LearningAgile Trends 2018 - Além da Automação com Machine Learning
Agile Trends 2018 - Além da Automação com Machine Learning
 
Qualidade de Código
Qualidade de CódigoQualidade de Código
Qualidade de Código
 
Slides exemplodeprocessoscrum
Slides exemplodeprocessoscrumSlides exemplodeprocessoscrum
Slides exemplodeprocessoscrum
 
5 dicas para estruturar seu teste de performance
5 dicas para estruturar seu teste de performance5 dicas para estruturar seu teste de performance
5 dicas para estruturar seu teste de performance
 
Code Smells: o que eles dizem sobre seu código?
Code Smells: o que eles dizem sobre seu código?Code Smells: o que eles dizem sobre seu código?
Code Smells: o que eles dizem sobre seu código?
 
Programação Orientada a Aspectos
Programação Orientada a AspectosProgramação Orientada a Aspectos
Programação Orientada a Aspectos
 
Testes Automatizados e Especificação Por Exemplo - Unindo TI e Negócio atravé...
Testes Automatizados e Especificação Por Exemplo - Unindo TI e Negócio atravé...Testes Automatizados e Especificação Por Exemplo - Unindo TI e Negócio atravé...
Testes Automatizados e Especificação Por Exemplo - Unindo TI e Negócio atravé...
 
Engenharia Requisitos
Engenharia RequisitosEngenharia Requisitos
Engenharia Requisitos
 
Sistema de tarefas 1.0
Sistema de tarefas 1.0Sistema de tarefas 1.0
Sistema de tarefas 1.0
 
Matando web forms e modernizando um grande varejista
Matando web forms e modernizando um grande varejistaMatando web forms e modernizando um grande varejista
Matando web forms e modernizando um grande varejista
 
Rumo à Certificação PHP
Rumo à Certificação PHPRumo à Certificação PHP
Rumo à Certificação PHP
 
TDC 2016 - Workshop sobre Planejamento Ágil de Releases
TDC 2016 - Workshop sobre Planejamento Ágil de ReleasesTDC 2016 - Workshop sobre Planejamento Ágil de Releases
TDC 2016 - Workshop sobre Planejamento Ágil de Releases
 
Aumente a performance de seu site de maneira disciplinada
Aumente a performance de seu site de maneira disciplinadaAumente a performance de seu site de maneira disciplinada
Aumente a performance de seu site de maneira disciplinada
 
Day 0 iniciando na carreira em ti
Day 0   iniciando na carreira em tiDay 0   iniciando na carreira em ti
Day 0 iniciando na carreira em ti
 
PHPZEIRO: Adote um framework
PHPZEIRO: Adote um frameworkPHPZEIRO: Adote um framework
PHPZEIRO: Adote um framework
 

Python Brasil 2022 - Queries performáticas com ORM em Python, Django e Postgres.pdf

  • 1. Queries performáticas com ORM em Python, Django e Postgres whatsgood.com.br Thiago Ferreira / Python Brasil 2022
  • 2. Sobre mim 🤖 Staff Software Engineer @ Routable 🐍 Pythonista 🌱 Entusiasta da cozinha (Insta: @maisumdiarioveg) 🐶 Pai de pet 🍿Mandem recomendações de filmes, séries e livros :P Github: @thiagoferreiraw Twitter e Medium: @tferreiraw Linkedin: https://www.linkedin.com/in/thiago-ferreira-380427a8/
  • 3. 🧾 Implementando queries complexas no ORM ❌ Erros comuns nas queries (N+1) 📚 Problemas complexos além do ORM: índices 🏅Menções honrosas: Ferramentas e dicas para auxiliar na organização e manutenção do ORM/queries 🎯 Conhecimento prático e com muitos exemplos Sumário
  • 4.
  • 5. Chico, boas-vindas ao time! Sua primeira tarefa será criar uma listagem de pedidos, exibindo ID, Nome e total vendido. Tranquilo?
  • 7. Listagem de pedidos 🧾 Primeira tarefa: implementar uma listagem de pedidos, exibindo ID, Nome do cliente e total.
  • 9. 🚨 Chico, os clientes estão reclamando que a listagem de pedidos está lenta. Poderia verificar?
  • 10. Será que o ORM é lento? É lentidão do python? Banco sobrecarregado? Já estraguei o brinquedo no primeiro dia de serviço 😖
  • 11. 1⃣ Visualizar as queries executadas 2⃣ Analisar o comando SQL gerado pelo ORM 3⃣ Otimizar de acordo com os resultados - sempre testando antes e depois. Identificando problemas no ORM em 3 passos:
  • 13. Por que tantas queries? Buscando apenas orders (sem customer) O customer é usado ao longo do programa, isso faz com que o Django busque os objetos sob demanda
  • 14. Queries extras em customer O Uma nova query para cada iteração da lista de orders (ids diferentes)
  • 15. Queries N+1 🚨 É um problema de performance, onde para cada iteração do laço principal (ex: Pedidos) é executada uma nova query para buscar dados adicionais (ex: Clientes) Então se temos 10 pedidos na consulta, teremos 1 query para os pedidos e + 10 queries extras para trazer os clientes
  • 16. Como resolver? Informamos ao ORM para já carregar o customer do banco de dados
  • 17. De 6 para 1 query 76%mais rápido que o anterior
  • 18. SQL joins e a teoria dos conjuntos
  • 21. Sem diferenças relevantes em relação ao ORM Melhoria de 0.6ms 😅 ~18% em relação ao ORM otimizado. Nada muito impressionante.
  • 22. 🧾 Segunda tarefa: Listar um pedido com seus respectivos itens (exibir nome do produto e categoria) Complicando um pouco - 1-N
  • 25. De 11 para 2 queries 73%mais rápido que o anterior
  • 26. Complicando MAIS: prefetch 🧾 Terceira tarefa: Listar vários pedidos com seus respectivos itens (exibir nome do produto e categoria)
  • 27. 45 queries (em 5 pedidos)
  • 28. Resolvendo: -> Items já estão carregados
  • 29. De 45 para 2 queries 91%mais rápido que o anterior
  • 30. Select related OU prefetch related? 👉 Select Related: - Utiliza um JOIN para trazer registros com relação direta Por ex: - Order.customer - Product.category - Item.product 👉 Prefetch Related: - Utiliza uma segunda query para trazer registros relacionados (1 ou vários): - Pode ser combinado com select related Por ex: - order.items
  • 31. 📈 Ao escrever queries com ORM, sempre considerar as relações que serão utilizadas 🌎 SQL é nosso amigo e nos ajuda a identificar problemas 🧾 O ORM oferece vantagens sobre o SQL puro, pois não precisamos nos preocupar com a sintaxe do SQL no nosso código 👤Os mesmo problemas mostrados anteriormente podem podem acontecer no Django Admin. Cuidado com o método __str__(self) Aprendizados com ORM
  • 32. Índices no banco de dados 📚 O que são índices? ❓ Como saber se preciso colocar um índice? 📄 Analisando o Query Plan do Postgres 🧐 Verificando se o índice é realmente usado
  • 33. Chico, vi que você está mandando muito bem na otimização de queries, poderia acertar essa outra página também?
  • 34. 🧾 Tarefa: Otimizar uma página lenta no website. A página lista o total vendido filtrando por email Otimizando além do ORM
  • 36. O que são índices?
  • 38. Analisando o query plan (visual) From: https://tatiyants.com/pev/#/plans/new
  • 41. Novo query plan após indexar
  • 42. Novo query plan (visual)
  • 43. Trade offs índices ➕ Considerar o tempo de inserção 🧐 O banco de dados pode não usar o índice ⛰ Volumetria importa ⏱ Espaço X tempo
  • 44. Espaço index Aumento de 31% no armazenamento para contemplar o índice
  • 45. Operação Problema Solução Melhoria Listar pedidos Queries extras Select_related -76% 13.8ms -> 3.2ms Listar um pedido com itens Queries extras Select_related em ambas queries -73% 24.2ms -> 6.4ms Listar múltiplos pedidos com itens Queries extras Select_related + prefetch_related -91% 95.9ms -> 8.4ms Consulta de orders por email Falta de índice no campo email Indexar o email -82% 16ms -> 2.8ms Resultados
  • 48. Signals - Código + desacoplado
  • 49. Extra: Queries mais complexas
  • 50. Extra: Quando as queries são executadas?
  • 51. Quando as queries são executadas?
  • 52. Querysets são “Lazy”, ou seja, não executam a query no banco de dados antes dos dados serem necessários Quando os dados são “necessários”? - Ao se fazer uma iteração (for loop) - Executar len(queryset) - Slicing: queryset[:10] - Listing: list(queryset) - Calling str() and repr() - Pickling/caching Quando as queries são executadas?
  • 53. Ferramentas auxiliares (em dev) 📈django-extensions: - python manage.py shell_plus --print-sql - python manage.py dbshell 📈 django-debug-toolbar: - Shows a debug toolbar on the web page 📈 django-queryinspect - Mostra estatísticas do SQL, ex: - [SQL] 17 queries (4 duplicates), 34 ms SQL time, 243 ms total request time 📈 Testes unitários - self.assertNumQueries(5) 📈 django-silk - Profilling for Django
  • 54. Ferramentas auxiliares (em prod) Ferramentas de observabilidade e monitoramento em geral: - Elastic APM - New Relic - Data Dog - Honeycomb - opentelemetry
  • 55. Conclusão 🐢 O ORM não é lento, só pode estar mal configurado 📚 Entender como os índices funcionam e como verificá-los nos ajuda a resolver problemas mais complexos 🛠 Existem muitas ferramentas disponíveis para auxiliar no debug e monitoramento de queries 󰞲 Sempre testar o antes e depois de mudanças para garantir que elas realmente são efetivas.
  • 57. Muito Obrigado! Bora pra discussão :) Github: @thiagoferreiraw Twitter e Medium: @tferreiraw Linkedin: https://www.linkedin.com/in/thiago-ferreira-380427a8/ Projeto de exemplo dos slides github.com/thiagofereriraw/django-orm-optimization-talk