Quando precisamos colocar uma busca em um sistema, normalmente a primeira solução que vem à cabeça é o LIKE.
Ele é fácil de entender, funciona no PostgreSQL e no MySQL e resolve boa parte das buscas simples:
SELECT titulo, subtitulo
FROM publicacoes
WHERE titulo LIKE '%postgresql%';Esse comando procura a palavra postgresql em qualquer parte do título. Para um sistema pequeno, com poucos registros, ele pode funcionar muito bem.
Então por que pensar em outra solução?
A resposta está no tipo de busca que queremos oferecer e na quantidade de dados que o sistema precisa consultar.
Por que o LIKE é tão utilizado?
O LIKE costuma ser a primeira escolha por alguns motivos:
- É simples de aprender.
- Não exige a criação de uma estrutura específica para busca.
- Funciona bem em tabelas pequenas.
- Pode procurar partes de uma palavra.
- Está disponível nos bancos de dados mais conhecidos.
Também é comum aprender LIKE logo no início dos estudos de SQL. Já o Full-Text Search exige entender índices, configuração de idioma e relevância dos resultados.
Portanto, usar LIKE não significa que o código esteja errado. O problema aparece quando ele é usado para realizar buscas mais completas em uma quantidade maior de textos.
Quando o LIKE pode se tornar um problema?
Uma busca como esta começa com o caractere %:
WHERE titulo LIKE '%postgresql%'Nesse caso, um índice B-tree comum normalmente não consegue ajudar da mesma forma que ajudaria em uma busca iniciada por um texto conhecido, como:
WHERE titulo LIKE 'postgresql%'Na primeira consulta, o banco pode precisar verificar uma quantidade maior de registros para encontrar o texto pesquisado.
Outro ponto é que o LIKE procura uma sequência de caracteres. Ele não foi criado para entender quais resultados são mais importantes.
Considere estas duas publicações:
PostgreSQL: criando uma busca com Full-Text Search
Configurando um servidor que utiliza PostgreSQLSe a pessoa pesquisar por PostgreSQL busca, o primeiro conteúdo provavelmente deveria aparecer antes. Com LIKE, seria necessário criar condições adicionais para tentar chegar a esse resultado.
O que muda com o Full-Text Search?
O Full-Text Search prepara os textos para que possam ser pesquisados como palavras, e não apenas como sequências de caracteres.
Com ele, podemos:
- Pesquisar várias palavras.
- Ordenar os resultados por relevância.
- Dar mais importância ao título do que ao subtítulo.
- Utilizar um índice próprio para busca textual.
- Tratar melhor pesquisas em campos com textos maiores.
No PostgreSQL, por exemplo, podemos definir que uma palavra encontrada no título tenha um peso maior do que a mesma palavra encontrada no subtítulo.
Criando um exemplo para testar
Primeiro, vamos criar uma tabela pequena:
CREATE TABLE publicacoes (
id SERIAL PRIMARY KEY,
titulo VARCHAR(200) NOT NULL,
subtitulo VARCHAR(255)
);Agora podemos inserir alguns conteúdos:
INSERT INTO publicacoes (titulo, subtitulo) VALUES
(
'PostgreSQL: busca com Full-Text Search',
'Como melhorar a pesquisa de publicações'
),
(
'Primeiros passos com PHP',
'Criando uma API conectada ao PostgreSQL'
),
(
'Configurando um servidor Linux',
'Preparação do ambiente para publicar uma aplicação'
);Antes de continuar, execute uma busca com LIKE:
SELECT id, titulo
FROM publicacoes
WHERE titulo ILIKE '%postgresql%'
OR subtitulo ILIKE '%postgresql%';Resultado esperado:
| id | titulo |
|---|---|
| 1 | PostgreSQL: busca com Full-Text Search |
| 2 | Primeiros passos com PHP |
O ILIKE é uma opção do PostgreSQL que realiza a comparação sem diferenciar letras maiúsculas de minúsculas.
Full-Text Search no PostgreSQL
No PostgreSQL, podemos criar uma coluna que prepara o título e o subtítulo para a busca:
ALTER TABLE publicacoes
ADD COLUMN busca_textual tsvector
GENERATED ALWAYS AS (
setweight(
to_tsvector('portuguese', coalesce(titulo, '')),
'A'
) ||
setweight(
to_tsvector('portuguese', coalesce(subtitulo, '')),
'B'
)
) STORED;O título recebeu o peso A, enquanto o subtítulo recebeu o peso B. Isso informa que uma palavra encontrada no título deve ter mais importância.
Em seguida, criamos um índice GIN:
CREATE INDEX publicacoes_busca_textual_idx
ON publicacoes
USING GIN (busca_textual);Agora podemos fazer a busca:
SELECT
id,
titulo,
ts_rank_cd(
busca_textual,
websearch_to_tsquery('portuguese', 'postgresql busca')
) AS relevancia
FROM publicacoes
WHERE busca_textual @@
websearch_to_tsquery('portuguese', 'postgresql busca')
ORDER BY relevancia DESC;O primeiro conteúdo tende a receber uma relevância maior porque possui as duas palavras pesquisadas no título.
A função websearch_to_tsquery também permite receber pesquisas mais próximas das que fazemos em um buscador. Ela aceita palavras, frases entre aspas e exclusões sem gerar erro facilmente por causa da forma como o usuário digitou.
E como funciona no MySQL?
No MySQL, primeiro criamos um índice FULLTEXT:
ALTER TABLE publicacoes
ADD FULLTEXT INDEX publicacoes_busca_idx (titulo, subtitulo);Depois utilizamos MATCH e AGAINST:
SELECT
id,
titulo,
MATCH(titulo, subtitulo)
AGAINST('postgresql busca' IN NATURAL LANGUAGE MODE)
AS relevancia
FROM publicacoes
WHERE MATCH(titulo, subtitulo)
AGAINST('postgresql busca' IN NATURAL LANGUAGE MODE)
ORDER BY relevancia DESC;O modo natural calcula a relevância dos registros encontrados. Também existe o modo booleano, que oferece operadores para exigir, excluir ou combinar termos.
PostgreSQL e MySQL fazem isso da mesma forma?
O objetivo é parecido, mas a implementação muda:
| PostgreSQL | MySQL |
|---|---|
Usa tsvector para armazenar o texto preparado | Usa um índice FULLTEXT nos campos |
Pesquisa com tsquery | Pesquisa com MATCH e AGAINST |
Pode usar ts_rank ou ts_rank_cd | O próprio MATCH retorna a relevância |
Permite configurar pesos com setweight | A relevância é calculada pelo mecanismo do MySQL |
| O índice GIN é indicado para esse tipo de busca | O índice utilizado é o FULLTEXT |
Não é necessário decorar todas essas funções. O mais importante é entender que cada banco possui sua própria maneira de preparar, indexar e pesquisar os textos.
O Full-Text Search também tem pontos negativos?
Sim. Ele não substitui o LIKE em todas as situações.
O Full-Text Search exige uma configuração inicial, ocupa espaço com índices e pode precisar de ajustes relacionados ao idioma e às palavras ignoradas pelo banco.
Também não é a melhor opção quando precisamos procurar apenas uma parte da palavra.
Por exemplo, uma busca por gres pode encontrar PostgreSQL com:
WHERE titulo ILIKE '%gres%'No Full-Text Search, isso pode não acontecer porque a pesquisa trabalha principalmente com palavras e termos preparados.
Palavras muito curtas também merecem atenção. O MySQL possui configurações de tamanho mínimo das palavras e listas de termos ignorados. Dependendo da configuração, uma palavra pode não entrar no índice.
Buscas com erros de digitação também não são resolvidas automaticamente. No PostgreSQL, a extensão pg_trgm pode ser uma alternativa quando o sistema precisa encontrar palavras parecidas ou incompletas.
Então qual devo usar?
O LIKE continua sendo uma boa escolha quando:
- A tabela possui poucos registros.
- A busca é simples.
- Precisamos encontrar parte de uma palavra.
- Não precisamos ordenar por relevância.
- O campo pesquisado possui valores curtos.
O Full-Text Search o quando:
- A busca envolve títulos, descrições ou textos maiores.
- O sistema possui muitos registros.
- Queremos pesquisar várias palavras.
- Precisamos mostrar primeiro os resultados mais relevantes.
- A busca é uma parte importante da experiência do usuário.
O que utilizei no meu projeto
Na busca de publicações do meu portfólio, utilizei Full-Text Search porque precisava pesquisar no título e no subtítulo, dando mais importância ao título.
No PostgreSQL, criei uma coluna tsvector, configurei o idioma como português e adicionei um índice GIN. A busca utiliza websearch_to_tsquery e os resultados são ordenados com ts_rank_cd.
Também preparei uma implementação para MySQL utilizando índice FULLTEXT e MATCH ... AGAINST.
O objetivo não foi apenas substituir uma consulta por outra. A mudança permitiu organizar os resultados por relevância e preparar a busca para o crescimento da quantidade de publicações.
Conclusão
O LIKE não é uma solução ruim. Ele é simples, útil e pode ser exatamente o que um projeto pequeno precisa.
O problema é continuar utilizando a mesma solução quando a busca começa a trabalhar com muitos textos, várias palavras e resultados que precisam ser organizados por importância.
O Full-Text Search exige um pouco mais de preparação, mas oferece recursos criados especificamente para pesquisa textual. Saber quando usar cada opção ajuda a evitar tanto consultas limitadas quanto uma estrutura mais complexa do que o projeto realmente precisa.

