Otimização de consultas SQL: Leia planos de execução e corrija consultas lentas, com intervalos
Pare de adivinhar por que uma consulta é lenta. Aprenda a ler um plano de execução e, em seguida, aplique as correções mais importantes, com medições de antes e depois de uma tabela real de um milhão de linhas.
- Comece com o plano de execução. Ele informa o que o banco de dados realmente faz.
- Procure verificações completas em tabelas grandes e adicione índices que correspondam aos seus filtros e junções.
- Evite agrupar uma coluna indexada em uma função, pois isso pode interromper o uso eficiente do índice.
- Meça antes e depois, porque cada banco de dados e conjunto de dados se comportam de maneira diferente.
Uma consulta que demorou milissegundos no ano passado pode demorar minutos hoje, simplesmente porque a tabela cresceu. A otimização de consultas SQL tem menos a ver com truques inteligentes e mais com um processo repetível: descubra o que o banco de dados está fazendo, remova o trabalho desperdiçado e verifique se isso ajudou.
Testamos cada técnica abaixo em um milhão de linhas geradas no SQLite 3.50. Os tempos são os melhores de várias execuções de um laptop, usando um banco de dados na memória. Eles não corresponderão ao seu sistema, e PostgreSQL, MySQL e SQL Server têm, cada um, seus próprios otimizadores e formatos de plano. Concentre-se no tamanho de cada melhoria e nos princípios por trás dela.
Resumo dos resultados
| Técnica | Antes | Depois |
|---|---|---|
| Índice na coluna de filtro | 73ms | 0,01ms |
| Intervalo em vez de uma função em uma coluna | 96ms | 33ms |
| Índice composto para dois filtros | 19ms | 2,2ms |
| Conjunto de chaves em vez de OFFSET profundo | 8,1ms | 0,01ms |
A configuração do teste
CREATE TABLE customers (
id INTEGER PRIMARY KEY, name TEXT, city TEXT
);
CREATE TABLE orders (
id INTEGER PRIMARY KEY, customer_id INT, status TEXT,
created TEXT, total INT, note TEXT
);
-- 50,000 customers and 1,000,000 orders with random values
Um processo simples de otimização
- Encontre as consultas importantes. Use registros de consultas lentas ou monitoramento. Uma consulta de 200 ms executada mil vezes por minuto pode ser mais importante do que um relatório mensal de 10 segundos.
- Leia o plano. Veja o que o banco de dados realmente está fazendo.
- Mude uma coisa. Adicione um índice ou reescreva parte da consulta.
- Meça novamente com dados realistas. Um plano de 100 linhas de teste diz muito pouco sobre um milhão.
- Acompanhe ao longo do tempo. Os planos podem mudar à medida que os dados crescem e as estatísticas mudam.
Leia um plano de execução
Um plano de execução é a estratégia passo a passo do banco de dados para executar uma consulta, incluindo quais índices ele usa e em que ordem ele une as tabelas. Prefixe uma consulta para vê-la:
| Banco de dados | Comando |
|---|---|
| SQLite | EXPLICAR CONSULTA PLANO SELECIONAR ... |
| PostgreSQL | EXPLICAR ANALISAR SELECIONAR ... |
| MySQL | EXPLAIN SELECT ... ou EXPLAIN ANALYZE |
| Servidor SQL | Plano de execução real no SSMS |
Observe que EXPLAIN ANALYZE no PostgreSQL realmente executa a consulta, então tome cuidado ao usá-lo com UPDATE ou DELETE. Aqui está o que procurar primeiro:
| Você vê | Significado | Normalmente |
|---|---|---|
| Varredura ou Varredura Seq | Lê a tabela inteira | Uma preocupação em mesas grandes |
| Pesquisa ou busca de índice | Salta para linhas correspondentes | Bom |
| Índice de cobertura | Respondido apenas pelo índice | Muito bom |
| Árvore Temp B ou Classificação | Trabalho extra de classificação | Vale a pena conferir |
Uma verificação completa não é automaticamente ruim. Se uma consulta precisar de uma tabela pequena, a digitalização pode ser a escolha mais rápida. No PostgreSQL EXPLAIN ANALYZE, compare também as linhas estimadas com as linhas reais. Uma grande diferença geralmente significa que as estatísticas da tabela estão desatualizadas.
Adicione o índice correto
Esta consulta encontra os pedidos de um cliente:
SELECT id, total FROM orders WHERE customer_id = 123;
Antes de adicionar um índice, o plano era uma verificação completa:
SCAN orders
-- 20 rows in 73 ms
Em seguida, adicionamos um índice na coluna do filtro:
CREATE INDEX idx_orders_customer ON orders(customer_id);
SEARCH orders USING INDEX idx_orders_customer (customer_id=?)
-- 20 rows in 0.01 ms
As mesmas 20 linhas voltaram milhares de vezes mais rápido, porque o banco de dados não lia mais um milhão de linhas para encontrá-las. Nenhuma outra técnica neste artigo nos proporcionou uma vitória maior. Bons primeiros candidatos são colunas usadas em WHERE, JOIN e ORDER BY, especialmente quando restringem os resultados a poucas linhas. Nosso guia sobre índices SQL explica como eles funcionam.
Não envolva colunas indexadas em funções
Aqui estão duas maneiras de encontrar pedidos de março, com índice em created:
-- Function on the column
SELECT id FROM orders WHERE substr(created, 1, 7) = '2026-03';
-- SCAN orders USING COVERING INDEX idx_orders_created
-- 84,961 rows in 96 ms
-- Plain range
SELECT id FROM orders
WHERE created >= '2026-03-01' AND created < '2026-04-01';
-- SEARCH orders USING COVERING INDEX idx_orders_created (created>? AND created<?)
-- 84,961 rows in 33 ms
Ambos retornam linhas idênticas, mas o primeiro demorou cerca de três vezes mais. O plano mostra o porquê: com uma função na coluna, o banco de dados não pode pular para uma posição no índice classificado, então precisa SCAN em cada entrada. A versão da gama pode SEARCH ir direto para o lugar certo. Uma condição que pode usar um índice dessa maneira é chamada sargable.
O mesmo problema aparece com estes padrões comuns:
| Evite | Prefiro |
|---|---|
ONDE ANO(criado) = 2026 |
WHERE criado >= '2026-01-01' E criado < '2027-01-01' |
ONDE preço * 2 > 100 |
ONDE preço > 50 |
ONDE INFERIOR(e-mail) = 'a@b.com' |
Um índice baseado em função ou um agrupamento que não diferencia maiúsculas de minúsculas |
ONDE nome LIKE '%99' |
Uma pesquisa de prefixo ou pesquisa de texto completo |
Verificamos esse último também. Um curinga inicial produzido SCAN customers, como um índice classificado a partir da primeira letra, não pode ajudar na correspondência no final.
Índices compostos
Quando uma consulta é filtrada em duas colunas, um índice de coluna única faz apenas parte do trabalho:
SELECT id FROM orders
WHERE status = 'paid'
AND created >= '2026-03-01' AND created < '2026-03-08';
-- Using only the created index: 6,198 rows in 19 ms
CREATE INDEX idx_status_created ON orders(status, created);
-- SEARCH orders USING COVERING INDEX idx_status_created
-- (status=? AND created>? AND created<?)
-- 6,198 rows in 2.2 ms
A ordem das colunas é muito importante. Um índice em (status, created) funciona como uma lista telefônica classificada por sobrenome e depois nome. Você pode procurar apenas um sobrenome, mas não apenas um nome. Somente nossa consulta em status poderia usar esse índice. Filtrar apenas created geralmente não poderia usá-lo de forma eficiente. Como regra geral, coloque as colunas testadas com igualdade primeiro e as colunas de intervalo depois delas.
Esse plano também diz abrangendo o índice, o que significa que o índice continha tudo o que a consulta precisava, portanto a tabela em si não precisava ser lida. Selecionar apenas as colunas necessárias torna isso mais provável, o que é outro motivo para evitar SELECT *.
Paginação mais rápida
Usar OFFSET para páginas profundas é um custo oculto, já que o banco de dados ainda precisa passar por todas as linhas ignoradas:
-- Page deep into the results
SELECT id FROM orders ORDER BY id LIMIT 20 OFFSET 500000;
-- 8.1 ms
-- Keyset pagination: continue from the last id seen
SELECT id FROM orders WHERE id > 500000 ORDER BY id LIMIT 20;
-- 0.01 ms
A paginação do conjunto de chaves permanece rápida, não importa o quão profundo você vá. Também evita a mudança de linhas entre páginas quando novos dados são adicionados. A desvantagem é que os usuários não podem ir direto para a página 5.000, o que raramente é uma necessidade real. Em tabelas com linhas largas ou com mais linhas para pular, a lacuna pode ser muito maior do que em nosso teste.
Dica: nossos tempos medem uma consulta por vez em uma máquina ociosa. Sob carga real, uma consulta ineficiente causa mais danos, porque também mantém bloqueios e compete por memória, disco e CPU com todo o resto.
Escreva consultas mais enxutas
- Selecione apenas as colunas necessárias.
SELECT *envia mais dados e pode impedir que um índice cubra a consulta. - Filtrar antecipadamente. Use
WHEREpara remover linhas antes do agrupamento eHAVINGapenas para condições em agregações. Consulte SQL GROUP BY e HAVING. - Use LIMIT quando precisar apenas de algumas linhas.
- Prefira UNION ALL quando não precisar remover duplicatas. Nosso teste UNION vs UNION ALL mostra o que isso economiza.
- Evite DISTINCT desnecessário. Muitas vezes, é ocultar uma junção que produz duplicatas.
- Use EXISTS para verificações de existência. Ele pode parar na primeira correspondência, como explica nosso guia para subconsultas SQL.
- Observe as consultas N+1. Uma consulta por linha em um loop, geralmente causada pelo código do aplicativo, costuma ser o problema real. Uma única consulta de junção ou em lote pode substituir centenas de viagens de ida e volta.
Junta-se
Indexe as colunas nas quais você se une. Geramos um relatório de gastos totais para clientes em uma cidade, e o plano era exatamente o que você esperava:
SELECT c.name, SUM(o.total)
FROM customers c
JOIN orders o ON o.customer_id = c.id
WHERE c.city = 'Goa'
GROUP BY c.id;
-- SCAN c
-- SEARCH o USING COVERING INDEX idx_cover (customer_id=?)
-- 9,900 rows in 34 ms
Ele verifica os clientes e depois usa um índice para localizar os pedidos de cada um. Sem um índice em orders.customer_id, o banco de dados teria que trabalhar muito mais para cada cliente. Um índice na chave estrangeira é uma das adições mais comuns e valiosas que você pode fazer. Para atualizar sua compreensão dos conceitos básicos, consulte Explicação sobre junções SQL.
Quando os índices custam caro
Os índices não são gratuitos, portanto não adicione um para cada coluna:
- Gravações mais lentas. Cada inserção, atualização e exclusão também deve atualizar cada índice.
- Mais armazenamento e memória. Os índices podem crescer muito em tabelas grandes.
- Pouco benefício em colunas não seletivas. Um índice em uma coluna verdadeira ou falsa pode não ajudar se a maioria das linhas corresponder.
- Redundância. Um índice em
(a)geralmente é desnecessário se você já tiver um em(a, b).
Verifique as estatísticas de uso periodicamente e remova índices que nada usa. E mantenha as estatísticas atualizadas com ANALYZE ou equivalente em seu banco de dados, porque o otimizador depende delas para escolher um bom plano. Às vezes, a parte lenta é a contenção, e não a consulta. Transações de longa duração que mantêm bloqueios podem fazer com que uma consulta rápida pareça lenta.
Erros comuns
- Otimizar sem medir. Muitas suposições confiantes revelam-se erradas.
- Testes com dados minúsculos. Os planos e os prazos mudam drasticamente à medida que as tabelas crescem.
- Confiar uma dica para outro banco de dados. Conselhos para um mecanismo podem não se aplicar a outro.
- Adicionando índices às cegas. Cada um deles retarda as gravações.
- Ignorando o efeito da primeira execução. Os caches tornam a segunda execução mais rápida, portanto, execute várias vezes.
Considerações finais
A maioria das consultas lentas tem causas comuns: um índice ausente, uma função em uma coluna ou muitos dados sendo buscados. Faça sua consulta real mais lenta desta semana, execute EXPLAIN nela e procure uma varredura completa em uma tabela grande. Corrija uma coisa, meça novamente e anote o que você mudou.
Perguntas frequentes
O que é otimização de consulta SQL?
É o processo de fazer com que as consultas utilizem menos tempo e menos recursos, geralmente examinando planos de execução, adicionando índices adequados e reescrevendo consultas ineficientes.
O que é um plano de execução?
É a estratégia escolhida pelo banco de dados para executar uma consulta, incluindo como ele lê as tabelas, quais índices ele usa e em que ordem ele se junta.
Como encontro consultas lentas?
Habilite o log de consultas lentas do seu banco de dados ou use ferramentas como pg_stat_statements no PostgreSQL. Em seguida, concentre-se nas consultas com maior tempo total.
Adicionar um índice sempre torna as consultas mais rápidas?
Não. Ajuda nas leituras seletivas, mas retarda as gravações e usa o armazenamento. O otimizador também poderá ignorá-lo se a maioria das linhas corresponder à condição.
SELECT * é ruim para o desempenho?
Pode ser. Ele transfere dados desnecessários e pode impedir que um índice cubra a consulta. Listar apenas as colunas necessárias geralmente é melhor.
Continue aprendendo
Precisa de ajuda com testes, WordPress ou SEO?
Ajudamos as equipes a fornecer software melhor e a expandir seus sites. Conte-nos no que você está trabalhando e sugeriremos um próximo passo claro.
Mais guias sobre testes, IA e desenvolvimento moderno
Gostou deste artigo? Escolha um tópico e vá direto para nossos tutoriais mais recentes.
Explicação das alucinações de IA: por que os modelos de linguagem inventam as coisas e como reduzi-las
Explicação das alucinações de IA: o que são, por que os modelos de linguagem as produzem, tipos comuns, como reduzi-las com aterramento e instruções…
Leia o artigo →DevOpsVariáveis de ambiente explicadas: arquivos .env, segredos e configuração bem feitos
Variáveis de ambiente explicadas com exemplos de Python que executamos: leitura e configuração, por que cada valor é uma string, arquivos .env, hera…
Leia o artigo →Desenvolvimento de softwareExplicação da limitação de taxa de API: algoritmos, cabeçalhos e tratamento de erros 429
Limitação de taxa de API explicada com uma simulação que executamos: token bucket, janela fixa, janela deslizante, 429 respostas, cabeçalhos de limi…
Leia o artigo →Automação de testesZombando em Python: unittest.mock, patch e os erros que fazem os testes mentirem
Zombaria em Python com unittest.mock, testado: Mock e return_value, side_effect, patch onde um nome é usado, especificação e autospec, zombaria de d…
Leia o artigo →Teste de softwareCobertura de código explicada: cobertura de linha versus filial e o que 100% realmente significa
Cobertura de código explicada com uma execução cobertura.py real: cobertura de linha, ramal e condição, leitura de um relatório, por que 100% de cob…
Leia o artigo →Bancos de dados e SQLDELETE vs TRUNCATE vs DROP em SQL: diferenças, reversão e quando usar cada um
DELETE vs TRUNCATE vs DROP explicado com SQL testado: o que cada um remove, rollback, aciona, redefinição de identidade, velocidade e como PostgreSQ…
Leia o artigo →Bancos de dados e SQLExibições SQL explicadas: crie, use e evite as armadilhas, com exemplos
Visualizações SQL explicadas com consultas que executamos: criação de uma visualização, resultados ao vivo, ocultação de colunas, desempenho, visual…
Leia o artigo →Desenvolvimento de softwareInterface TypeScript vs tipo: diferenças reais, testadas com o compilador
Interface TypeScript versus tipo, verificada com o compilador real: o que ambos podem fazer, o que apenas um pode fazer, mesclagem de declarações, e…
Leia o artigo →Desenvolvimento de softwarePython *args e **kwargs explicados: funções flexíveis com exemplos claros
Python *args e **kwargs explicados com o código que executamos: empacotamento e descompactação, ordem dos parâmetros, argumentos somente de palavras…
Leia o artigo →Desenvolvimento de softwareFunções Python Lambda: sintaxe, usos reais e quando não usá-los
Funções lambda do Python explicadas com o código que executamos: sintaxe, classificação com chave, mapa e filtro, fechamentos, armadilha de ligação …
Leia o artigo →Inteligência artificialO que são agentes de IA? Como eles funcionam, com um loop de agente simples que você pode executar
O que são agentes de IA? Um guia simples para o loop do agente, ferramentas, memória e proteções, com um pequeno loop Python que executamos, riscos …
Leia o artigo →DevOpsMonitoramento versus observabilidade: a verdadeira diferença, com logs, métricas e rastreamentos
Explicação do monitoramento versus observabilidade: falhas conhecidas e desconhecidas, logs, métricas e rastreamentos, um passo a passo do incidente…
Leia o artigo →DevOpsDocker Volumes vs Bind Mounts: persista os dados do contêiner da maneira certa
Volumes Docker versus montagens de ligação explicadas: por que os dados do contêiner desaparecem, volumes nomeados, montagens de ligação, tmpfs, exe…
Leia o artigo →Automação de testesTDD vs BDD: principais diferenças, um recurso criado de ambas as maneiras e quando usar cada um
TDD vs BDD explicado com um recurso de desconto construído em ambos os sentidos: refatoração vermelho-verde com o código que executamos, cenários da…
Leia o artigo →Teste de softwareTeste de aceitação do usuário (UAT): processo, lista de verificação e exemplos reais
Explicação do teste de aceitação do usuário: quem o executa, como ele difere do controle de qualidade, um processo de sete etapas, um modelo de caso…
Leia o artigo →Bancos de dados e SQLValores SQL NULL explicados: IS NULL, COALESCE, NULLIF e as armadilhas a serem evitadas
Valores SQL NULL explicados com consultas que executamos: lógica de três valores, IS NULL, COALESCE, NULLIF, como agregações, junções e classificaçã…
Leia o artigo →Bancos de dados e SQLInstrução SQL CASE WHEN: sintaxe, exemplos reais e erros comuns
SQL CASE WHEN explicado com consultas que executamos: formulários simples e pesquisados, ordem de condição, pivôs com SUM, truques COUNT, classifica…
Leia o artigo →Desenvolvimento de softwareO que é JWT? JSON Web Tokens explicados com um exemplo prático
O que é JWT? JSON Web Tokens explicados: as três partes, um token construído e adulterado no código que executamos, JWT vs sessões, armazenamento, t…
Leia o artigo →Desenvolvimento de softwareLoop de eventos JavaScript explicado: pilha de chamadas, microtarefas e temporizadores com exemplos
O loop de eventos JavaScript explicado com o código que executamos: pilha de chamadas, filas de tarefas e microtarefas, por que setTimeout 0 não é i…
Leia o artigo →Desenvolvimento de softwareGeradores Python e rendimento explicado: economize memória com exemplos reais
Geradores Python e rendimento explicados com o código que executamos: como eles pausam e reiniciam, medem economia de memória, pipelines, sequências…
Leia o artigo →Inteligência artificialO que são incorporações? Similaridade de vetores e cossenos explicada de forma simples
O que são incorporações? Um guia em linguagem simples para vetores, similaridade de cossenos e pesquisa semântica, com um pequeno exemplo que execut…
Leia o artigo →DevOpsImplantação azul-verde vs canário: diferenças, compensações e como escolher
Explicação da implantação azul-verde versus canário: como cada um funciona, custo, risco e reversão, agrupamento estável de usuários que testamos, m…
Leia o artigo →Automação de testesTestes instáveis: o que os causa e como corrigi-los para sempre
Testes instáveis explicados com demonstrações que executamos: as principais causas, como confirmar e diagnosticar uma, soluções adequadas para tempo…
Leia o artigo →Teste de softwareTeste de carga versus teste de estresse: diferenças, métricas e exemplos k6
Teste de carga versus teste de estresse explicado: o que cada um prova, testes de pico e absorção, as métricas que importam, por que as médias engan…
Leia o artigo →Teste de softwareCaso de teste versus cenário de teste: principais diferenças, exemplos e quando usar cada um
Caso de teste vs cenário de teste explicado: definições claras, uma tabela lado a lado, um recurso de redefinição de senha retirado de cenários para…
Leia o artigo →Bancos de dados e SQLOtimização de consultas SQL: leia planos de execução e corrija consultas lentas, com intervalos
Otimização de consulta SQL testada em um milhão de linhas: leia planos de execução, adicione os índices corretos, corrija filtros não sargáveis, use…
Leia o artigo →Bancos de dados e SQLSQL UNION vs UNION ALL: diferenças, exemplos e desempenho testado
SQL UNION vs UNION ALL explicado com consultas que executamos: duplicatas, as regras que ambos seguem, um bug de dados real, desempenho medido, INTE…
Leia o artigo →Desenvolvimento de softwareTutorial da API JavaScript Fetch: GET, POST, tratamento de erros e tempos limite
Um tutorial da API JavaScript Fetch testado em um servidor local: GET e POST, por que 404 não lança, um auxiliar reutilizável, strings de consulta, …
Leia o artigo →Desenvolvimento de softwareManipulação de arquivos Python: leitura, gravação, CSV, JSON e pathlib com exemplos
Manipulação de arquivos Python explicada com código que executamos: modos abertos, com, leitura de arquivos grandes, CSV, JSON, pathlib, arquivos bi…
Leia o artigo →Desenvolvimento de softwareClasses e objetos Python: tutorial OOP com exemplos reais
Classes e objetos Python explicados com código que executamos: __init__, métodos, atributos de classe vs instância, herança, propriedades, métodos d…
Leia o artigo →Inteligência artificialO que é um modelo de linguagem grande? Como funcionam os LLMs, explicado sem exageros
O que é um modelo de linguagem grande? LLMs explicados em linguagem simples: tokens, incorporações, atenção, treinamento, temperatura e janelas de c…
Leia o artigo →DevOpsComandos Linux para iniciantes: o guia essencial do terminal com exemplos
Comandos Linux para iniciantes, agrupados por tarefa: navegação, arquivos, visualização de logs, grep, pipes, permissões, processos e arquivos, com …
Leia o artigo →Automação de testesSelenium vs Playwright: principais diferenças, código comparado e qual escolher
Selenium vs Playwright comparado: arquitetura, espera, suporte a navegador e linguagem, depuração, o mesmo teste em ambas as ferramentas, conselhos …
Leia o artigo →Teste de softwareParticionamento de equivalência: técnica de design de teste explicada com exemplos resolvidos
Explicação do particionamento de equivalência: como encontrar partições válidas e inválidas, exemplos resolvidos para idades, senhas e cupons, teste…
Leia o artigo →Teste de softwareGravidade vs Prioridade em Testes de Software: Diferenças, Matriz e Exemplos Reais
Explicação da gravidade versus prioridade em testes de software: definições claras, uma matriz de quatro vias com exemplos, escalas de nível, quem d…
Leia o artigo →Bancos de dados e SQLTutorial de subconsultas SQL: tipos, subconsultas correlacionadas e EXISTS com exemplos
Um tutorial de subconsultas SQL com consultas que executamos: subconsultas escalares, IN, FROM e SELECT, subconsultas correlacionadas, EXISTS, a arm…
Leia o artigo →Bancos de dados e SQLTransações SQL e ACID explicados: COMMIT, ROLLBACK e níveis de isolamento
Transações SQL e ACID explicadas com uma transferência bancária que executamos: COMMIT, ROLLBACK, savepoints, locks, níveis de isolamento, leituras …
Leia o artigo →Desenvolvimento de softwareFolha de dicas dos comandos do Git: os comandos que você realmente usa, com exemplos
Uma folha de dicas de comandos Git agrupada por tarefa: configuração, preparação, ramificações, controles remotos, stash, histórico e desfazer erros…
Leia o artigo →Desenvolvimento de softwareExplicação das promessas de JavaScript: então, catch, Promise.all e erros comuns
Promessas JavaScript explicadas com o código que executamos: estados, cadeias then e catch, tratamento de erros, Promise.all, allSettled, race e any…
Leia o artigo →Desenvolvimento de softwareTutorial do dicionário Python: métodos, exemplos e padrões comuns
Um tutorial de dicionário Python com código que executamos: criar, ler e atualizar dictos, métodos-chave, mesclagem, compreensão, padrões de contage…
Leia o artigo →Inteligência artificialO que é RAG? Geração aumentada de recuperação explicada com um exemplo prático
O que é RAG? Geração aumentada de recuperação explicada passo a passo: indexação, chunking, embeddings, recuperação, um pequeno exemplo funcional de…
Leia o artigo →DevOpsTutorial Terraform para iniciantes: infraestrutura como código do primeiro arquivo aos módulos
Um tutorial do Terraform para iniciantes: comece sem conta na nuvem, aprenda como iniciar, planejar e aplicar, depois variáveis, saídas, estado, mód…
Leia o artigo →DevOpsDocker vs Kubernetes: principais diferenças, como eles funcionam juntos e o que você precisa
Docker vs Kubernetes explicado: o que cada um faz, o mesmo aplicativo rodando com ambos, Docker Compose e Swarm comparados, a mudança do dockershim …
Leia o artigo →Automação de testesTutorial Pytest para iniciantes: luminárias, parametrização e exemplos reais
Um tutorial pytest para iniciantes com testes que executamos no pytest 9.2: asserções, fixtures, parametrizar, conftest, marcadores, tmp_path, monke…
Leia o artigo →Teste de softwareCiclo de vida de teste de software (STLC): 6 fases, critérios de entrada e saída, exemplo
O ciclo de vida de teste de software explicou: seis fases do STLC com critérios de entrada e saída, resultados, um exemplo de recurso de login funci…
Leia o artigo →Desenvolvimento de softwareGit merge vs rebase: diferenças, exemplos e quando usar cada um
Git merge vs rebase explicado com saída real do log, uma tabela comparativa, a regra de ouro do rebase e um fluxo de trabalho seguro para equipes.
Leia o artigo →Desenvolvimento de softwareList comprehension em Python: sintaxe, exemplos e quando evitar
List comprehension em Python explicada: sintaxe, filtros, if-else, laços aninhados, tempos medidos e quando um laço for comum é a melhor escolha.
Leia o artigo →Bancos de dados e SQLSQL JOIN explicado com exemplos (Inner, Left, Right, Full)
Entenda os joins SQL passo a passo com tabelas e consultas de exemplo: INNER, LEFT, RIGHT, FULL, CROSS e SELF, além de erros comuns e dicas de desem…
Leia o artigo →