Tópico 10 de 12

Otimização e Performance

As técnicas que mais aparecem na prática para deixar um sistema rápido: cache, processamento assíncrono, concorrência, SQL eficiente e CDN.

O que estudar

  • Cache-Aside Pattern
  • Jobs assíncronos
  • Concorrência e paralelismo
  • Otimização e performance de SQLProblema N+1 · Índices
  • CDN

Exemplos visuais

Sem cache x Cache-Aside

GET /api/v1/products/best-sellers

Sem cache

Clientes
×1000 req
API
query
Banco

Toda requisição vai ao banco — a mesma consulta pesada roda milhares de vezes.

Cache-Aside

Clientes
×1000 req
API
1. get
Redis
hit ✓
API
miss
2. query
Banco
3. set
Redis

A API consulta o cache primeiro. Só em caso de miss busca no banco e grava o resultado no cache.

Processamento síncrono x assíncrono

Sem processamento assíncrono

Cliente
POST
API
e-mail + PDF + ...
~5 s
Resposta

O cliente espera tudo terminar — enviar e-mail, gerar PDF, chamar serviços externos — antes de receber a resposta.

Com processamento assíncrono

Cliente
POST
API
~50 ms
202 Accepted
API
publica
Fila
RabbitMQ
consome
Worker

A API só publica uma mensagem na fila e responde na hora. Workers processam o trabalho pesado em segundo plano.

O problema N+1

Uma consulta para buscar a lista e, depois, uma consulta extra para cada item. Com 500 usuários, são 501 idas ao banco.

❌ N+1 — uma consulta por usuário

import sqlite3

conn = sqlite3.connect('example.db')
cursor = conn.cursor()

cursor.execute("SELECT id, name FROM users")
users = cursor.fetchall()

for user_id, name in users:
    cursor.execute(
        "SELECT title FROM articles WHERE user_id = ?",
        (user_id,),
    )
    articles = cursor.fetchall()
    # 1 + N consultas...

✅ Uma única consulta com JOIN

cursor.execute("""
    SELECT u.id, u.name, a.title
    FROM users u
    LEFT JOIN articles a ON a.user_id = u.id
""")
rows = cursor.fetchall()

# SQL executado pelo código N+1:
# SELECT id, name, email FROM users;
# SELECT title FROM articles WHERE user_id = 1;
# SELECT title FROM articles WHERE user_id = 2;
# ...
# SELECT title FROM articles WHERE user_id = 500;
Fluxo do cache-aside: a aplicação lê do cache; em caso de miss, busca no banco e atualiza o cache
Cache-aside: a aplicação consulta o cache primeiro e só vai ao banco em caso de miss. Fonte: EnjoyAlgorithms.

Artigos7

Vídeos1