Publicado em

O que são índices SQL? Por que são importantes e como funcionam

Autores

    O que são índices SQL? Por que são importantes e como funcionam

    Os índices são uma das ferramentas mais importantes para melhorar o desempenho dos bancos de dados.

    Neste artigo, você aprenderá:

    • O que são índices SQL
    • Por que aceleram tanto as consultas
    • Como criá-los
    • Um exemplo que mostra diferenças de desempenho
    • Como funcionam internamente

    Vamos tornar os índices intuitivos.

    O que é um índice?

    Um índice em SQL é uma estrutura de dados especial (geralmente uma árvore B) que permite ao banco de dados encontrar linhas muito mais rapidamente, sem percorrer toda a tabela.

    Você pode imaginar um índice como:

    • Uma lista ordenada de valores
    • Cada valor aponta para uma linha na tabela principal
    • Organizado para que o banco de dados possa pesquisá-lo rapidamente (tempo logarítmico)

    Sem índice → o banco de dados precisa verificar cada linha.
    Com índice → o banco de dados vai diretamente aos valores correspondentes.

    Por que os índices SQL foram criados

    Os índices existem para resolver um problema:

    Acelerar consultas que procuram valores específicos.

    Eles foram criados porque as varreduras completas de tabelas se tornam lentas demais à medida que os conjuntos de dados crescem.
    Em uma tabela com 10 linhas, percorrer todas é rápido.
    Em uma tabela com 10 milhões de linhas, fazer isso repetidamente se torna inviável.

    Os índices permitem:

    • Buscas rápidas
    • Ordenação rápida (ORDER BY)
    • Junções rápidas
    • Verificações de unicidade rápidas (por meio de um índice UNIQUE)

    Bancos de dados como PostgreSQL, MySQL e SQLite dependem deles.

    Exemplo com JOINs

    Os índices também aceleram drasticamente os JOINs.

    Vamos usar as tabelas users e orders:

    SELECT users.name, orders.product
    FROM orders
    JOIN users ON orders.user_id = users.id
    WHERE users.email = 'bob@example.com';
    

    Índices recomendados

    CREATE INDEX idx_users_email ON users(email);
    CREATE INDEX idx_orders_user_id ON orders(user_id);
    

    Sem índices: varreduras completas das duas tabelas

    Quando não existem índices em users.email e orders.user_id, o banco de dados precisa:

    • Percorrer cada linha de users para encontrar as linhas que correspondem à condição de e-mail
    • Percorrer cada linha de orders para encontrar as linhas cujo user_id corresponde aos IDs desses usuários

    Isso é chamado de varredura sequencial ou varredura completa da tabela.

    Escala do exemplo:

    • Tabela users: 100.000 linhas
    • Tabela orders: 1.000.000 de linhas

    O banco de dados precisa examinar:

    • 100.000 linhas de usuários
    • 1.000.000 de linhas de pedidos

    Embora o resultado final possa ser uma única linha, o custo da busca é muito alto.

    Desempenho aproximado (varia conforme a máquina):

    • Verificação de 100 mil usuários + 1 milhão de pedidos
    • Sem índices: aproximadamente 300 a 600 ms
    • Com índices: aproximadamente 1 a 3 ms

    Isso representa uma melhoria de 100 a 500 vezes.

    Com índices: busca rápida e direta

    Com os dois índices:

    • idx_users_email → permite encontrar instantaneamente o usuário com aquele e-mail
    • idx_orders_user_id → permite encontrar instantaneamente todos os pedidos daquele usuário

    Em vez de percorrer milhões de linhas:

    • O banco de dados vai diretamente às entradas corretas no índice (uma busca em árvore B)
    • Apenas as linhas relevantes são acessadas
    • O JOIN se torna extremamente rápido

    O que influencia o desempenho?

    O tempo exato varia conforme o hardware, mas estes fatores da máquina são os mais importantes:

    FatorEfeito
    Tipo de disco (SSD ou HDD)Enorme impacto: SSDs são de 10 a 100 vezes mais rápidos para acesso aleatório
    Quantidade de RAMSe as tabelas e os índices couberem na memória, as consultas ficam drasticamente mais rápidas
    Velocidade da CPUAfeta a velocidade de varredura dos nós da árvore B
    Cache de buffersCaches aquecidos tornam consultas repetidas muito mais rápidas
    Tamanho da tabelaQuanto maior a tabela, mais importantes se tornam os índices

    Os índices são essenciais nas aplicações porque até máquinas poderosas têm dificuldade com varreduras completas e repetidas de tabelas à medida que os dados crescem.

    • Sem índices: o banco de dados precisa ler cada linha das duas tabelas
    • Com índices: o banco de dados realiza buscas rápidas usando estruturas de dados eficientes
    • Isso permite que os JOINs escalem para milhões de linhas com tempos de resposta de milissegundos

    Como os índices funcionam internamente (explicação simples)

    A maioria dos bancos de dados SQL usa árvores B, que:

    • Mantêm os valores ordenados
    • Permitem uma busca semelhante à busca binária
    • Têm uma profundidade extremamente pequena (geralmente de 3 a 5 níveis, mesmo em tabelas enormes)

    Isso significa que:

    • Encontrar uma linha exige apenas algumas comparações
    • O acesso é previsível e rápido
    • Os índices crescem de forma logarítmica, não linear

    Você não precisa entender o algoritmo em profundidade, mas esta é a ideia principal:

    É muito mais rápido pesquisar em uma árvore ordenada do que em um milhão de linhas desordenadas.

    Quando você deve usar um índice?

    Use um índice quando você:

    • Usa SELECT com frequência para buscar dados com base em uma coluna
    • Filtra com WHERE
    • Ordena usando ORDER BY
    • Faz JOIN entre tabelas por chaves estrangeiras
    • Garante unicidade (UNIQUE INDEX)
    • Pesquisa usando consultas por igualdade ou intervalo

    Os índices são mais valiosos em:

    • e-mail
    • nome de usuário
    • created_at
    • chaves estrangeiras (user_id, post_id)
    • slugs
    • colunas de busca

    Quando não usar um índice

    Os índices têm custos:

    • Ocupam espaço em disco
    • Tornam as escritas mais lentas (INSERT/UPDATE/DELETE precisam atualizar o índice)

    Evite indexar:

    • colunas booleanas
    • colunas de cardinalidade muito baixa (por exemplo, gênero, status = “ativo”)
    • colunas raramente usadas em consultas
    • colunas de texto muito grandes