Come viene implementato LIKE?


22

Qualcuno può spiegare come viene implementato l'operatore LIKE negli attuali sistemi di database (ad esempio MySQL o Postgres)? o mi punta ad alcuni riferimenti che lo spiegano?

L'approccio ingenuo sarebbe quello di ispezionare ogni record, eseguendo un'espressione regolare o una corrispondenza di stringa parziale sul campo di interesse, ma ho la sensazione (speranza) che questi sistemi facciano qualcosa di più intelligente.

Risposte:


19

No, è praticamente quello che stanno facendo. Ora, se non è presente un carattere jolly iniziale e il campo è indicizzato, come al solito, il motore di database può applicare l'espressione regolare all'indice. Quindi, per esempio, se scrivi

SELECT *
  FROM employees
 WHERE last_name LIKE 'Cav%'

il database può utilizzare l'indice su LAST_NAME per trovare tutte le righe in cui il cognome inizia "Cav". D'altra parte, se avessi qualcosa del genere

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

il database dovrebbe scansionare l'intera tabella (o l'intero indice) e valutare l'espressione rispetto al LAST_NAMEvalore completo . Ovviamente, è molto costoso.

La maggior parte dei migliori database relazionali dispone di strutture per eseguire ricerche full-text in modo più efficiente costruendo diversi tipi di indici e cataloghi di testo, ma questi non usano la parola chiave LIKE. Ad esempio, ecco un bell'articolo che discute della ricerca full-text in PostgreSQL .


4
Oracle può utilizzare un indice anche con una percentuale iniziale. Se i dati ricercati rappresentano un piccolo sottoinsieme delle righe, il suggerimento può costringerlo a utilizzare un indice e rendere più veloce l'esecuzione. Vedi laurentschneider.com/wordpress/2009/07/… .
Leigh Riffel,

1
"scansiona l'intera tabella ... Ovviamente, è molto costoso" - dipende piuttosto dalla tabella;) ps sei d'accordo LAST_NAMEa candidarti (nella prima colonna) dell'indice cluster? pps in che misura questa risposta presuppone che il sistema di database sia basato su una memoria contigua su indici del disco e B-tree?
giorno

26

Oltre a ciò che ha scritto Justin Cave, da PostgreSQL 9.1 puoi velocizzare qualsiasi ricerca con LIKE( ~~) o ILIKE( ~~*) e anche corrispondenze di espressioni regolari di base ( ~). Utilizzare le classi di operatori fornite dal modulo pg_trgm con un indice GIN o GiST per accelerare le LIKEespressioni che non sono ancorate a sinistra. Per installare l'estensione, eseguire una volta per database:

CREATE EXTENSION pg_trgm;

Crea un indice del modulo

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

O:

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

Creazione e manutenzione di un indice GIN o GiST comporta un costo, ma se la tabella non è scritta in modo pesante, questa è una grande funzionalità per te.

Depesz ha scritto un eccellente articolo nel suo blog sulla nuova funzionalità.

GIN o GiST?

Queste due citazioni del manuale dovrebbero fornire alcune indicazioni

La scelta tra l'indicizzazione GiST e GIN dipende dalle caratteristiche relative alle prestazioni di GiST e GIN, che sono discusse altrove. Come regola generale, un indice GIN è più veloce da cercare rispetto a un indice GiST, ma più lento da costruire o aggiornare; quindi GIN è più adatto per dati statici e GiST per dati spesso aggiornati.

Ma per il tipo di query "vicino più vicino" con l'utilizzo dell'operatore distanza <->:

Questo può essere implementato in modo abbastanza efficiente dagli indici GiST, ma non dagli indici GIN.


3
Leggendo questo mi chiedevo se usare GIN o GiST. Secondo quanto ho letto, gli indici GIN sono più costosi da mantenere ma più veloci da cercare, mentre un indice GiST è più economico da mantenere ma più lento da cercare. Ciò significa che gli indici GIN dovrebbero generalmente essere utilizzati su dati relativamente statici, mentre gli indici GiST sono preferiti su tabelle con mutazioni più pesanti.
Colin 't Hart,

1
@ Colin'tHart: è generalmente vero, ma ci sono eccezioni alla regola. Considera l'addendum sopra.
Erwin Brandstetter,

5

Parlando di MySQL, la posizione del carattere jolly (%) fa la differenza. Se la prima parte del testo è specificata come where first_name like 'Sta%', allora il motore DB cercherà solo un sottoinsieme più piccolo di parole che fissano con S, poi vanno a St, e poi a Sta, ecc. Se si fa qualcosa di simile where first_name like '%stan%', allora e l'intera scansione del sarà richiesta la colonna. Puoi anche esaminare gli indici full-text che eseguono anche ricerche in linguaggio naturale. Dai un'occhiata ai documenti di MySQL qui.


1
Perché dovrebbe iniziare a cercare "S%" quando la sottostringa è definita su 3 caratteri (ovvero sappiamo che la stringa non è "Sr%")? O pensavi che il DB avesse un albero dei prefissi sugli attributi e fornisse un esempio di attraversamento di questo albero?
Nick,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.