Wie wird LIKE implementiert?


22

Kann jemand erklären, wie der LIKE-Operator in aktuellen Datenbanksystemen (z. B. MySQL oder Postgres) implementiert ist? oder zeigst du mir ein paar Hinweise, die es erklären?

Der naive Ansatz wäre, jeden Datensatz zu untersuchen, indem ein regulärer Ausdruck oder eine Teilzeichenfolgenübereinstimmung für das betreffende Feld ausgeführt wird, aber ich habe das Gefühl (die Hoffnung), dass diese Systeme etwas Klügeres tun.

Antworten:


19

Nein, das ist so ziemlich das, was sie tun. Wenn jetzt kein führender Platzhalter vorhanden ist und das Feld indiziert ist, was in der Regel der Fall ist, kann das Datenbankmodul den regulären Ausdruck auf den Index anwenden. So zum Beispiel, wenn Sie schreiben

SELECT *
  FROM employees
 WHERE last_name LIKE 'Cav%'

Die Datenbank kann den Index für verwenden LAST_NAME, um alle Zeilen zu finden, in denen der Nachname "Cav" beginnt. Auf der anderen Seite, wenn Sie so etwas hatten

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

Die Datenbank müsste die gesamte Tabelle (oder den gesamten Index) durchsuchen und den Ausdruck anhand des vollständigen LAST_NAMEWerts auswerten . Das ist natürlich sehr teuer.

Die meisten der besseren relationalen Datenbanken verfügen über Funktionen zur effizienteren Volltextsuche, indem verschiedene Arten von Indizes und Textkatalogen erstellt werden, die jedoch nicht das Schlüsselwort LIKE verwenden. In diesem Artikel wird beispielsweise die Volltextsuche in PostgreSQL beschrieben .


4
Oracle kann sogar einen Index mit einem führenden Prozentsatz verwenden. Wenn die gesuchten Daten eine kleine Teilmenge der Zeilen darstellen, kann der Hinweis die Verwendung eines Index erzwingen und die Ausführung beschleunigen. Siehe laurentschneider.com/wordpress/2009/07/… .
Leigh Riffel

1
"die gesamte tabelle scannen ... das ist natürlich sehr teuer" - das hängt eher von der tabelle ab;) ps sind LAST_NAMEsie ein kandidat für (die erste spalte in) den clustered index? pps Inwieweit geht diese Antwort davon aus, dass das Datenbanksystem auf zusammenhängendem Speicher auf Datenträgern und B-Tree-Indizes basiert?
Eintägig, wenn der

26

Zusätzlich zu dem, was Justin Cave geschrieben hat, können Sie seit PostgreSQL 9.1 jede Suche mit LIKE( ~~) oder ILIKE( ~~*) beschleunigen und auch grundlegende Übereinstimmungen mit regulären Ausdrücken ( ~). Verwenden Sie die Operator-Klassen, die vom Modul pg_trgm mit einem GIN- oder GiST-Index bereitgestellt werden LIKE, um nicht verankerte Ausdrücke zu beschleunigen . Führen Sie einmal pro Datenbank aus, um die Erweiterung zu installieren:

CREATE EXTENSION pg_trgm;

Erstellen Sie einen Index des Formulars

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

Oder:

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

Das Erstellen und Verwalten eines GIN- oder GiST-Index ist mit Kosten verbunden. Wenn Ihre Tabelle jedoch nicht stark geschrieben ist, ist dies eine großartige Funktion für Sie.

Depesz hat in seinem Blog einen ausgezeichneten Artikel über die neue Funktion geschrieben.

GIN oder GIST?

Diese beiden Anführungszeichen aus dem Handbuch sollten eine Orientierungshilfe sein

Die Wahl zwischen der Indizierung von GiST und GIN hängt von den relativen Leistungseigenschaften von GiST und GIN ab, die an anderer Stelle erörtert werden. Als Faustregel gilt, dass ein GIN-Index schneller zu durchsuchen ist als ein GiST-Index, jedoch langsamer zu erstellen oder zu aktualisieren ist. Daher eignet sich GIN besser für statische Daten und GiST für häufig aktualisierte Daten.

Bei Abfragen vom Typ "nächster Nachbar" mit dem Distanzoperator <->:

Dies kann von GiST-Indizes sehr effizient implementiert werden, jedoch nicht von GIN-Indizes.


3
Als ich dies las, fragte ich mich, ob ich GIN oder GiST verwenden sollte. Nach meiner Lektüre sind GIN-Indizes teurer in der Pflege, aber schneller in der Suche, während ein GiST-Index billiger in der Pflege, aber langsamer in der Suche ist. Dies bedeutet, dass GIN-Indizes im Allgemeinen für relativ statische Daten verwendet werden sollten, während GiST-Indizes für stärker mutierende Tabellen bevorzugt werden.
Colin 't Hart

1
@ Colin'tHart: Das stimmt im Allgemeinen, aber es gibt Ausnahmen von der Regel. Betrachten Sie den Anhang oben.
Erwin Brandstetter

5

Bei MySQL macht die Position des Platzhalterzeichens (%) einen Unterschied. Wenn der erste Teil des Textes wie angegeben wird where first_name like 'Sta%', dann werden die DB - Engine suchen nur eine kleinere Teilmenge von Worten mit S starren, dann nach St. gehen, und dann Sta, etc. Wenn Sie etwas tun , wie where first_name like '%stan%', dann und gesamte Scan des Spalte wird benötigt. Sie können auch in Volltextindizes suchen, in denen auch nach natürlichen Sprachen gesucht wird. Schauen Sie sich hier die MySQL-Dokumente an.


1
Warum wird die Suche nach "S%" gestartet, wenn die Teilzeichenfolge aus 3 Zeichen besteht (dh wir wissen, dass die Zeichenfolge nicht "Sr%" ist)? Oder haben Sie angenommen, dass die DB einen Präfixbaum über den Attributen hat, und ein Beispiel für das Durchlaufen dieses Baums angegeben?
Nick
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.