Boas Práticas de SQL: Otimize Suas Consultas e Organize Seu Código

Se você está começando com MySQL ou busca melhorar suas habilidades, este post traz uma seleção de boas práticas de SQL do básico ao avançado.

As boas práticas de SQL deixam as consultas mais rápidas, legíveis e seguras. Entre as principais: evite SELECT * e selecione só as colunas necessárias; filtre os dados com WHERE bem definido; use índices nas colunas mais consultadas; prefira JOINs explícitos a subconsultas desnecessárias; e organize o código com comentários, indentação e nomes claros.

Essas dicas são essenciais para otimizar suas consultas e organizar seu código. Ideal para iniciantes, mas com dicas úteis até para quem já tem experiência, essas práticas vão te ajudar a escrever queries mais eficientes e legíveis.

Dicas para Iniciantes

Caso prefira esse conteúdo no formato de vídeo-aula, assista ao vídeo abaixo ou acesse o nosso canal do YouTube!

O que você aprende neste vídeo

Resposta rápida: Nesta aula, o instrutor traz 5 boas práticas de SQL no MySQL para otimizar e organizar as consultas. Entre elas: evitar o SELECT * (consultar só as colunas necessárias), usar comentários no código (quem/quando alterou), indentar bem (SELECT, FROM, WHERE em linhas separadas), dar nomes claros às tabelas e usar o GROUP BY para agrupamentos, tornando o código mais legível e eficiente.

Neste vídeo (16 min):

  • 0:00 - 5 boas práticas de SQL no MySQL para otimizar e organizar.
  • 2:00 - Evitar o SELECT *: consultar só as colunas necessárias.
  • 6:00 - Usar comentários no código (quem alterou e quando).
  • 10:00 - Indentar bem: SELECT, FROM e WHERE em linhas separadas.
  • 12:00 - Nomes claros de tabelas e o GROUP BY para agrupamentos.

Se você está começando agora a aprender SQL, temos um post perfeito pra você: Saia do Zero em SQL em apenas um post!

Evite Usar SELECT * e Otimize Suas Consultas

Uma prática comum, mas não recomendada, é logo de cara usar SELECT * para visualizar todas as colunas de uma tabela.

Isso pode sobrecarregar o processamento, especialmente em tabelas grandes com dezenas de colunas e milhares de linhas.

Em vez disso, opte por selecionar apenas as colunas necessárias.

Por exemplo, em uma tabela de clientes com 100 linhas, ao invés de dar SELECT * FROM clientes, use SELECT nome, email, telefone, renda_anual FROM clientes.

Isso vai reduzir o volume de dados processados, tornando a consulta mais rápida e eficiente, mesmo que o código fique um pouco mais longo.

tabela com colunas selecionadas

Filtre os Dados com Eficiência Usando WHERE

Além de evitar colunas desnecessárias, filtre também as linhas desnecessárias.

Use o comando WHERE para segmentar os dados e trazer apenas o que é relevante.

Por exemplo, se você quer apenas os clientes do gênero masculino, em vez de usar SELECT nome, email, telefone FROM clientes, escreva SELECT nome, email, telefone FROM clientes WHERE genero = ‘Masculino’.

Isso vai diminuir o número de linhas processadas, acelerando a consulta e otimizando o desempenho, especialmente em bases de dados maiores.

tabela apenas com masculinos

Melhore a Legibilidade com Comentários no Código

Comentários são essenciais para tornar seu código mais claro e facilitar sua manutenção.

Em MySQL, você pode usar -- para comentários de uma linha ou /* */ para blocos de várias linhas.

Por exemplo, adicione -- Atualizado em 15/02/2025 por Juliano Freitas para documentar mudanças.

Isso ajuda na manutenção do código, especialmente em equipes, facilitando que outros desenvolvedores (ou você no futuro) entendam o propósito de cada trecho.

Comentários não afetam a execução, mas aumentam a clareza e possibilitam a colaboração.

exemplo de comentários

Organize Seu Código com Quebras de Linha e Identação

Um código bem organizado é mais fácil de ler e entender.

Use quebras de linha e identação para estruturar suas consultas.

Por exemplo, podemos escrever SELECT nome, email, telefone FROM clientes WHERE genero = 'Masculino' em uma única linha:

SQL
SELECT Nome, Email, Telefone FROM clientes WHERE Genero = 'M';

Mas é preferível que se escreva o mesmo código com quebras de linha e indentações:

SQL
SELECT
    Nome,
    Email,
    Telefone
FROM
    clientes
WHERE genero = 'Masculino';

A identação (com tabs ou espaços) e as quebras de linha deixam o código mais legível, especialmente em consultas complexas com GROUP BY, ORDER BY ou JOIN.

Comece com Consultas Simples e Evolua Gradualmente

Para iniciantes, é melhor construir consultas complexas aos poucos.

Por exemplo, se você precisa do total de clientes por escolaridade, ordenado do menor para o maior, divida o processo em etapas: 

1. Comece com `SELECT * FROM clientes` para visualizar os dados. 

2. Adicione a contagem: `SELECT COUNT(*) AS total FROM clientes`. 

3. Agrupe por escolaridade: `SELECT escolaridade, COUNT(*) AS total FROM clientes GROUP BY escolaridade`. 

4. Ordene: `SELECT escolaridade, COUNT(*) AS total FROM clientes GROUP BY escolaridade ORDER BY total ASC`. 

Essa abordagem facilita encontrar erros e chegar ao resultado correto sem se perder.

Quer aprender mais comandos para consultas em SQL? Aprenda os principais comandos que permitem consultar, inserir, atualizar e excluir itens em bancos de dados SQL.

Essas cinco boas práticas – evitar `SELECT *`, filtrar com `WHERE`, usar comentários, organizar com quebras de linha e começar com consultas simples – são passos fundamentais para quem está começando com MySQL.

São ações que ajudam a criar consultas mais rápidas, organizadas e fáceis de manter, preparando você para desafios maiores.

Ícone SQLSQL Impressionador

Domine a linguagem mais importante do Mundo para quem trabalha com Dados, seja para se destacar na sua empresa atual, para conseguir um diferencial em processos seletivos ou até mesmo para entrar em áreas de dados.

Começar agoraSeta para a direita
Fundo SQLTelas SQL
Luz SQL

Dicas para Nível Intermediário

Caso prefira esse conteúdo no formato de vídeo-aula, assista ao vídeo abaixo ou acesse o nosso canal do YouTube!

Use Índices para Otimizar Consultas

Índices são ferramentas poderosas para melhorar a performance de consultas, especialmente em tabelas com muitas linhas. No entanto, usá-los corretamente exige entender como o MySQL processa suas queries.

Por exemplo, se você faz consultas frequentes com WHERE ou JOIN em colunas específicas, criar um índice nessas colunas pode reduzir drasticamente o tempo de execução. Suponha que você tem uma tabela pedidos com milhões de registros e frequentemente filtra por data_pedido. Sem um índice, o MySQL faz uma varredura completa na tabela (full table scan), o que é lento. Com um índice, a busca é muito mais rápida.

Exemplo:

SQL
CREATE INDEX idx_data_pedido ON pedidos(data_pedido);
SELECT * FROM pedidos WHERE data_pedido = '2025-05-01';

Ponto de atenção: Não crie índices em excesso, pois eles aumentam o tempo de operações de escrita (INSERT, UPDATE, DELETE) e consomem espaço. Analise as consultas mais frequentes com EXPLAIN para identificar onde os índices são realmente necessários:

SQL
EXPLAIN SELECT * FROM pedidos WHERE data_pedido = '2025-05-01';

Essa prática garante que suas consultas sejam otimizadas para grandes volumes de dados, mas exige cuidado para balancear desempenho de leitura e escrita.

Prefira JOINs Explícitos e Evite Subconsultas Desnecessárias

Embora subconsultas sejam úteis, elas podem ser menos eficientes que JOINs em muitos casos, especialmente em bases de dados grandes. Subconsultas forçam o MySQL a executar consultas aninhadas, o que pode ser custoso.

Por exemplo, para obter clientes que fizeram pedidos em 2025, você poderia usar uma subconsulta:

SQL
SELECT nome, email
FROM clientes
WHERE id_cliente IN (
    SELECT id_cliente
    FROM pedidos
    WHERE YEAR(data_pedido) = 2025
);

Mas um JOIN explícito é geralmente mais eficiente:

SQL
SELECT c.nome, c.email
FROM clientes c
INNER JOIN pedidos p ON c.id_cliente = p.id_cliente
WHERE YEAR(p.data_pedido) = 2025;

Dica: Use INNER JOIN para registros que devem existir em ambas as tabelas e LEFT JOIN quando você precisa de todos os registros da tabela à esquerda, mesmo que não haja correspondência. Sempre especifique as condições de junção no ON para maior clareza e desempenho. Além disso, prefira apelidos curtos (como c e p) para legibilidade, como visto na prática intermediária de ALIAS.

Gerencie Transações para Garantir Integridade de Dados

Em aplicações críticas, como sistemas financeiros, é essencial garantir que múltiplas operações sejam executadas como uma unidade atômica. Para isso, use transações no MySQL com os comandos START TRANSACTION, COMMIT e ROLLBACK.

Por exemplo, ao transferir um valor entre duas contas bancárias, você precisa atualizar dois registros de forma segura:

SQL
START TRANSACTION;
UPDATE contas SET saldo = saldo - 100 WHERE id_conta = 1;
UPDATE contas SET saldo = saldo + 100 WHERE id_conta = 2;
COMMIT;

Se algo der errado (como um erro na segunda atualização), você pode reverter com:

SQL
ROLLBACK;

Boa prática: Sempre defina um ponto de reversão com ROLLBACK em caso de falhas e use transações apenas quando necessário, pois elas podem bloquear linhas e impactar a concorrência em sistemas com muitos usuários.

Evite Correlações em Subconsultas e Use CTEs para Maior Clareza

Subconsultas correlacionadas (que dependem de valores da consulta externa) podem ser lentas, pois são executadas para cada linha da tabela externa. Considere usar Common Table Expressions (CTEs) para melhorar desempenho e legibilidade.

Por exemplo, para calcular a média de pedidos por cliente e listar apenas aqueles acima da média, uma subconsulta correlacionada seria:

SQL
SELECT nome, (
    SELECT COUNT(*) 
    FROM pedidos p 
    WHERE p.id_cliente = c.id_cliente
) AS total_pedidos
FROM clientes c
WHERE (
    SELECT COUNT(*) 
    FROM pedidos p 
    WHERE p.id_cliente = c.id_cliente
) > (SELECT AVG(total) FROM (
    SELECT COUNT(*) AS total 
    FROM pedidos 
    GROUP BY id_cliente
) AS medias);

Com uma CTE, o código fica mais claro e potencialmente mais eficiente:

SQL
WITH pedidos_por_cliente AS (
    SELECT id_cliente, COUNT(*) AS total_pedidos
    FROM pedidos
    GROUP BY id_cliente
),
media_pedidos AS (
    SELECT AVG(total_pedidos) AS media
    FROM pedidos_por_cliente
)
SELECT c.nome, ppc.total_pedidos
FROM clientes c
JOIN pedidos_por_cliente ppc ON c.id_cliente = ppc.id_cliente
WHERE ppc.total_pedidos > (SELECT media FROM media_pedidos);

CTEs permitem estruturar consultas complexas e blocos reutilizáveis, facilitando manutenção e otimizando o plano de execução do MySQL.

Monitore e Otimize com EXPLAIN e SHOW PROCESSLIST

Para consultas complexas, entender como o MySQL executa suas queries é crucial. O comando EXPLAIN mostra o plano de execução, indicando se índices estão sendo usados, quantas linhas são examinadas e se há gargalos. Por exemplo:

SQL
EXPLAIN SELECT nome, email 
FROM clientes 
WHERE genero = 'Masculino' 
AND data_nascimento >= '1990-01-01';

Analise a saída para verificar se há full table scans ou índices não utilizados. Além disso, use SHOW PROCESSLIST para monitorar consultas em execução em tempo real, especialmente em servidores com alta carga:

SQL
SHOW PROCESSLIST;

Isso ajuda a identificar consultas lentas ou bloqueios. Combine essas ferramentas com ajustes em índices e reescrita de consultas para garantir que seu código seja eficiente, mesmo em cenários de grande escala.

Dicas Avançadas

Caso prefira esse conteúdo no formato de vídeo-aula, assista ao vídeo abaixo ou acesse o nosso canal do YouTube!

Use UPDATE e DELETE com WHERE para Evitar Desastres

Uma prática fundamental que muitas pessoas não adotam é usar sempre UPDATE e DELETE com a cláusula WHERE para garantir que apenas os registros desejados sejam modificados ou excluídos. Sem WHERE, essas operações afetam todas as linhas da tabela, o que pode causar perda irreversível de dados.

Exemplo perigoso (evite):

SQL
UPDATE clientes SET renda_anual = 50000;

Isso atualiza a coluna renda_anual de todos os clientes para 50000. Em vez disso, especifique o alvo:

Exemplo seguro:

SQL
UPDATE clientes
SET renda_anual = 50000
WHERE id_cliente = 3;

O mesmo vale para DELETE:

SQL
DELETE FROM clientes WHERE id_cliente = 3;

Boa prática: Sempre revise seu código antes de executar UPDATE ou DELETE. Em raros casos, você pode precisar afetar todas as linhas (ex.: resetar uma coluna para um valor padrão), mas isso deve ser intencional e bem documentado.

Nota: Use transações (START TRANSACTION, COMMIT, ROLLBACK) para adicionar uma camada extra de segurança, como visto nas dicas intermediárias.

Combine LIMIT e ORDER BY para Resultados Consistentes

Ao usar LIMIT para restringir o número de linhas retornadas, combine-o com ORDER BY para evitar resultados aleatórios. Sem ORDER BY, o MySQL não garante a ordem dos registros, o que pode confundir análises ou levar a interpretações erradas.

Exemplo incorreto (resultados imprevisíveis):

SQL
SELECT nome, renda_anual
FROM clientes
LIMIT 50;

Os 50 primeiros registros podem variar a cada execução, dependendo de como o banco processa a tabela. Para consistência, faça da seguinte forma.

Exemplo correto:

SQL
SELECT nome, renda_anual
FROM clientes
ORDER BY renda_anual DESC
LIMIT 5;

Aqui, obtemos os 5 clientes com maior renda anual, ordenados de forma decrescente, ideal para criar um “Top 5”. Essa prática garante resultados previsíveis e é especialmente útil em relatórios ou dashboards.

Boa prática: Sempre defina a ordem desejada com ORDER BY antes de aplicar LIMIT, mesmo em consultas exploratórias.

Reutilize Consultas com CREATE VIEW para Ganhar Produtividade

Consultas repetitivas podem ser armazenadas como views para simplificar o trabalho e aumentar a eficiência. Uma view é uma consulta salva no banco de dados que pode ser reutilizada como se fosse uma tabela virtual, eliminando a necessidade de reescrever códigos complexos.

Exemplo:

SQL
CREATE VIEW vw_clientes_por_escolaridade AS
SELECT escolaridade, COUNT(*) AS total
FROM clientes
GROUP BY escolaridade;

Agora você pode consultar a view diretamente:

SQL
SELECT * FROM vw_clientes_por_escolaridade;

Vantagens:

  • Economiza tempo ao evitar recriar consultas frequentes.
  • Centraliza a lógica, facilitando manutenção (altere a view, e todas as consultas que a usam são atualizadas).
  • Melhora a legibilidade em projetos com muitas consultas repetitivas.

Boa prática: Use views para consultas recorrentes, como relatórios diários ou análises agregadas, mas evite views excessivamente complexas que possam impactar a performance.

4. Entenda a Diferença entre WHERE e HAVING para Filtros Precisos

Filtrar dados antes ou depois de um agrupamento faz toda a diferença no resultado de uma consulta. Use WHERE para filtrar linhas antes do agrupamento (GROUP BY) e HAVING para filtrar grupos depois do agrupamento.

Exemplo com WHERE (filtrar antes de agrupar):

SQL
SELECT escolaridade, COUNT(*) AS total
FROM clientes
WHERE genero = 'Masculino'
GROUP BY escolaridade;

Aqui, primeiro filtramos apenas clientes masculinos e depois agrupamos por escolaridade. O total reflete apenas os 48 clientes masculinos (exemplo da transcrição).

Exemplo com HAVING (filtrar depois de agrupar):

SQL
SELECT escolaridade, COUNT(*) AS total
FROM clientes
GROUP BY escolaridade
HAVING total >= 25;

Aqui, agrupamos todos os clientes por escolaridade e depois filtramos apenas os grupos com 25 ou mais clientes (ex.: 46 e 27, conforme a transcrição).

Boa prática: Use WHERE para condições em linhas individuais e HAVING para condições em dados agregados. Confundir os dois pode levar a resultados incorretos ou desempenho ruim.

Use Subconsultas Dinâmicas no Lugar de Valores Fixos

Subconsultas (um SELECT dentro de outro) permitem criar filtros dinâmicos, evitando valores fixos que podem se tornar obsoletos. Isso é especialmente útil quando os dados mudam frequentemente.

Exemplo com valor fixo (evite):

SQL
SELECT nome, preco_unitario
FROM produtos
WHERE preco_unitario >= 1788;

Se a média dos preços mudar (ex.: novos produtos forem adicionados), o valor 1788 ficará desatualizado. Em vez disso:

Exemplo com subconsulta:

SQL
SELECT nome, preco_unitario
FROM produtos
WHERE preco_unitario >= (
    SELECT AVG(preco_unitario)
    FROM produtos
);

Aqui, a subconsulta calcula a média dos preços automaticamente, garantindo que o filtro seja sempre atual. Na transcrição, a média foi 1788,125, e a subconsulta reflete qualquer alteração nos dados.

Boa prática: Substitua valores fixos por subconsultas quando o valor depende de cálculos dinâmicos. Para consultas mais complexas, considere usar CTEs (como nas dicas intermediárias) para maior clareza.

Esses são passos importantes para quem quer dominar SQL em um nível mais avançado. Elas ajudam a criar consultas mais rápidas, robustas e escaláveis, preparando você para trabalhar com sistemas complexos e grandes volumes de dados.

Continue aprendendo com nossos cursos, dicas e tutoriais gratuitos sobre SQL!

Hashtag Treinamentos

Para acessar outras publicações de SQL, clique aqui!


Quer aprender mais sobre SQL com um minicurso básico gratuito?

Posts mais recentes de SQL

Posts mais recentes da Hashtag Treinamentos

Perguntas frequentes

1. Quais são as boas práticas de SQL?

Evitar SELECT *, filtrar com WHERE eficiente, usar índices nas colunas mais consultadas, preferir JOINs explícitos, gerenciar transações e manter o código legível com comentários e indentação. Essas práticas melhoram desempenho e manutenção.

2. Por que evitar SELECT * no SQL?

Porque ele traz todas as colunas, inclusive as que você não precisa, consumindo mais memória e rede e deixando a consulta mais lenta. Selecionar apenas as colunas necessárias melhora o desempenho e deixa claro quais dados o código usa.

3. Para que servem os índices no SQL?

Índices funcionam como o índice de um livro: ajudam o banco a localizar registros rapidamente, sem varrer a tabela inteira. Criados nas colunas mais usadas em filtros e junções, aceleram bastante as consultas em tabelas grandes.

4. Qual a diferença entre JOIN explícito e implícito?

O JOIN explícito usa a palavra JOIN com a condição em ON, deixando a relação clara e fácil de ler. O implícito junta tabelas só listando-as no FROM com filtros no WHERE, o que confunde e facilita erros. O explícito é a prática recomendada.