Limites da busca com LIKE
A intuição errada do LIKE na busca
Por que a primeira solução que vem à mente (LIKE %termo%) costuma falhar em relevância e escala.
Nesta aula você vai
- Reconhecer por que LIKE com curingas parece óbvio e ainda assim é uma má escolha para busca textual
- Separar filtragem por substring de recuperação ordenada por relevância
- Antecipar o impacto de LIKE em catálogos grandes e com muitos usuários simultâneos
A intuição errada do LIKE na busca
Objetivos
Nesta aula você vai:
- Entender por que
LIKE '%termo%'surge como reflexo imediato e onde essa intuição falha - Distinguir “encontrei a substring” de “mostrei o resultado mais útil”
- Situar o custo desse padrão em um catálogo realista de livros digitais
Introdução
Quando um product owner pede “busca por título ou descrição”, a mão do desenvolvedor quase sempre escreve um WHERE titulo LIKE '%termo%'. O padrão é familiar, funciona no laboratório com dez linhas e passa no teste manual. O problema não é a sintaxe: é a metáfora errada. Buscar texto em um sistema de informação não é o mesmo que filtrar células de uma planilha.
Imagine a Estante Norte, um catálogo SaaS de livros técnicos e ficção para clubes de leitura. Há 420 mil obras, cada uma com título, subtítulo e sinopse. O usuário digita rede neural. Com LIKE, o banco devolve qualquer linha que contenha esses caracteres em qualquer ordem relativa — inclusive um romance cuja sinopse menciona “a rede neural do personagem” numa metáfora, e omite um tratado clássico intitulado apenas Redes Neurais Artificiais se a consulta for mal montada. Mais grave: a lista chega sem noção de prioridade. O primeiro resultado pode ser o menos útil.
Conteúdo
O reflexo LIKE e o que ele realmente faz
LIKE compara padrões de caracteres. O % significa “qualquer sequência”. Portanto:
-- Estante Norte: busca ingênua
SELECT id, titulo, autor
FROM obras
WHERE titulo LIKE '%rede neural%'
OR sinopse LIKE '%rede neural%';
Essa consulta responde a uma pergunta estreita: existe a sequência de caracteres rede neural em algum lugar dessas colunas? Ela não responde: quais obras são as mais pertinentes para quem procura esse tema?
| Pergunta do usuário | O que LIKE responde | O que a UX precisa |
|---|---|---|
| “Quero livros sobre redes neurais” | Linhas com a substring | Lista ordenada por pertinência |
| “Priorize o título” | Tudo no mesmo saco OR | Peso maior no campo título |
| “Ignore artigos e flexões” | Exige o texto literal | Tokenização e stemming |
Por que o laboratório engana
Com mil linhas e um único usuário, a latência parece aceitável. O plano de execução esconde o custo porque o buffer cache absorve a varredura. Em produção, a Estante Norte atende picos de 800 buscas por minuto no horário de abertura das turmas. Cada consulta com %termo% tende a varrer páginas inteiras da tabela; o custo cresce com o volume de dados e com a concorrência.
-- Mesmo padrão, agora em descrição longa
SELECT id, titulo
FROM obras
WHERE sinopse LIKE '%aprendizado de máquina%'
ORDER BY publicado_em DESC
LIMIT 20;
O ORDER BY acima ordena por data de publicação, não por relevância. A interface parece “organizada”, mas a organização não é a que o leitor pediu.
Sintomas que o time confunde com “falta de índice”
Equipes costumam reagir criando índices B-tree em titulo ou sinopse. Isso ajuda predicados do tipo titulo = '...' ou titulo LIKE 'prefixo%', mas não salva LIKE '%termo%': o curinga à esquerda impede o uso eficiente do índice. A intuição “índice resolve tudo” falha junto com a intuição do próprio LIKE.
Problema comum e solução
Problema: o time entrega busca com LIKE, usuários reclamam de resultados “aleatórios” e a API de busca satura o banco no pico.
Solução conceitual: tratar busca textual como problema de recuperação de informação — tokens, índice invertido e ranking — e reservar LIKE para casos pontuais (códigos internos, trechos exatos curtos, filtros administrativos). Nas próximas aulas deste módulo você verá full-text no MySQL e no PostgreSQL; aqui o ponto é abandonar a metáfora da planilha.
Como analisar
Antes de reescrever a feature, meça o plano atual:
-- PostgreSQL
EXPLAIN (ANALYZE, BUFFERS)
SELECT id, titulo
FROM obras
WHERE sinopse LIKE '%aprendizado de máquina%'
LIMIT 20;
-- MySQL
EXPLAIN
SELECT id, titulo
FROM obras
WHERE sinopse LIKE '%aprendizado de máquina%'
LIMIT 20;
Observe Seq Scan / ALL, número de rows estimadas e tempo real. Se a tabela cresce e o tempo cresce quase linearmente, você tem evidência empírica — não opinião — de que a intuição do LIKE não escala.
Resumo
LIKE '%termo%'responde “substring presente?”, não “melhor resultado para o usuário”- Índices B-tree tradicionais não salvam curingas à esquerda
- Em catálogos grandes e concorrentes, o custo explode mesmo quando o laboratório “passa no teste”
- A saída correta é full-text search com ranking;
LIKEfica para nichos