Como o LIKE é implementado?


22

Alguém pode explicar como o operador LIKE é implementado nos sistemas de banco de dados atuais (por exemplo, MySQL ou Postgres)? ou me aponte para algumas referências que explicam isso?

A abordagem ingênua seria inspecionar cada registro, executando uma expressão regular ou uma correspondência parcial de cadeias de caracteres no campo de interesse, mas tenho a sensação (esperança) de que esses sistemas façam algo mais inteligente.

Respostas:


19

Não, isso é o que eles estão fazendo. Agora, se não houver um curinga inicial e o campo estiver indexado, que é a situação usual, o mecanismo de banco de dados poderá aplicar a expressão regular ao índice. Então, por exemplo, se você escrever

SELECT *
  FROM employees
 WHERE last_name LIKE 'Cav%'

o banco de dados pode usar o índice LAST_NAMEpara encontrar todas as linhas em que o sobrenome começa 'Cav'. Por outro lado, se você tivesse algo como

SELECT *
  FROM employees
 WHERE last_name LIKE '%av%'

o banco de dados precisaria verificar a tabela inteira (ou o índice inteiro) e avaliar a expressão em relação ao LAST_NAMEvalor total . Obviamente, isso é muito caro.

A maioria dos melhores bancos de dados relacionais possui recursos para fazer pesquisa de texto completo de maneira mais eficiente, construindo diferentes tipos de índices e catálogos de texto, mas eles não usam a palavra-chave LIKE. Por exemplo, aqui está um bom artigo que discute a pesquisa de texto completo no PostgreSQL .


4
A Oracle pode usar um índice mesmo com uma porcentagem principal. Se os dados pesquisados ​​representarem um pequeno subconjunto das linhas, a dica poderá forçá-lo a usar um índice e tornar a execução mais rápida. Veja laurentschneider.com/wordpress/2009/07/… .
Leigh Riffel

1
"varre a tabela inteira ... Obviamente, isso é muito caro" - isso depende da tabela;) ps você concorda em LAST_NAMEser candidato ao (a primeira coluna do) índice indexado em cluster? pps até que ponto essa resposta assume que o sistema de banco de dados é baseado em armazenamento contínuo em índices de disco e árvore B?
precisa saber é o seguinte

26

Além do que Justin Cave escreveu, desde o PostgreSQL 9.1, você pode acelerar qualquer pesquisa com LIKE( ~~) ou ILIKE( ~~*), além de correspondências básicas de expressões regulares ( ~). Use as classes de operadores fornecidas pelo módulo pg_trgm com um índice GIN ou GiST para acelerar LIKEexpressões que não estão ancoradas à esquerda. Para instalar a extensão, execute uma vez por banco de dados:

CREATE EXTENSION pg_trgm;

Crie um índice do formulário

CREATE INDEX tbl_col_gin_trgm_idx ON tbl USING gin (col gin_trgm_ops);

Ou:

CREATE INDEX tbl_col_gist_trgm_idx ON tbl USING gist (col gist_trgm_ops);

Criando e mantendo um índice GIN ou GiST acarreta um custo, mas se sua tabela não for muito escrita, esse é um ótimo recurso para você.

Depesz escreveu um excelente artigo em seu blog sobre o novo recurso.

GIN ou GiST?

Essas duas citações do manual devem fornecer algumas orientações

A escolha entre a indexação GiST e GIN depende das características de desempenho relativas do GiST e GIN, que são discutidas em outros lugares. Como regra geral, um índice GIN é mais rápido para pesquisar do que um índice GiST, mas mais lento para compilar ou atualizar; portanto, o GIN é mais adequado para dados estáticos e o GiST para dados atualizados com frequência.

Mas para o tipo de consultas "vizinho mais próximo" com o operador using the distance <->:

Isso pode ser implementado com eficiência pelos índices GiST, mas não pelos índices GIN.


3
Ao ler isso, pensei em usar GIN ou GiST. De acordo com o que li, os índices GIN são mais caros para manter, mas mais rápidos para pesquisar, enquanto um índice GiST é mais barato para manter, mas mais lento para pesquisar. Isso significa que os índices GIN geralmente devem ser usados ​​em dados relativamente estáticos, enquanto os índices GiST são preferidos em tabelas com mais mutação.
Colin 't Hart

1
@ Colin'tHart: Isso geralmente é verdade, mas há exceções à regra. Considere o adendo acima.
Erwin Brandstetter

5

Falando sobre o MySQL, a posição do caractere curinga (%) faz a diferença. Se a primeira parte do texto for especificada como where first_name like 'Sta%', o mecanismo de banco de dados pesquisará apenas um subconjunto menor de palavras com S, passando para St e Sta, etc. Se você fizer algo parecido where first_name like '%stan%', faça uma varredura completa do coluna será necessária. Você também pode procurar em índices de texto completo que também fazem pesquisas em idiomas naturais. Confira os documentos do MySQL aqui.


1
Por que ele começaria a pesquisar "S%" quando a substring é definida com 3 caracteres (ou seja, sabemos que a string não é "Sr%")? Ou você estava assumindo que o banco de dados possui uma árvore de prefixo sobre os atributos e fornecendo um exemplo de como percorrer essa árvore?
Nick
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.