Weiß jemand, was die Komplexität für den SQL-Operator LIKE
für die beliebtesten Datenbanken ist?SQL `LIKE` Komplexität
Antwort
Betrachten wir die drei Kernfälle getrennt voneinander. Diese Diskussion ist MySQL-spezifisch, könnte aber auch auf andere DBMS angewendet werden, da Indizes typischerweise auf ähnliche Weise implementiert werden.
LIKE 'foo%'
ist schnell, wenn auf einer indizierten Spalte ausgeführt wird. MySQL-Indizes sind eine Variation von B-Bäumen. Wenn Sie diese Abfrage durchführen, kann sie einfach den Baum auf den Knoten foo
oder den ersten Knoten mit diesem Präfix absenken und den Baum vorwärts durchqueren. All dies ist sehr effizient.
LIKE '%foo'
kann nicht durch Indizes beschleunigt werden und führt zu einem vollständigen Tabellenscan. Wenn Sie andere Kriterien haben, die mithilfe von Indizes ausgeführt werden können, werden nur die Zeilen durchsucht, die nach der ersten Filterung übrig bleiben.
ein Trick, obwohl Es gibt: Wenn Sie Suffix passende tun müssen, um - mit der Erweiterung für Dateinamen suchen .foo
, zum Beispiel - Sie durch Hinzufügen einer Spalte mit dem gleichen Inhalt wie das Original die gleiche Leistung erzielen können, aber mit die Zeichen in umgekehrter Reihenfolge.
ALTER TABLE my_table ADD COLUMN col_reverse VARCHAR (256) NOT NULL;
ALTER TABLE my_table ADD INDEX idx_col_reverse (col_reverse);
UPDATE my_table SET col_reverse = REVERSE(col);
für Zeilen mit col
in .foo
endende Suche wird dann:
SELECT * FROM my_table WHERE col_reverse LIKE 'oof.%'
Schließlich gibt es noch LIKE '%foo%'
, für die keine Abkürzungen gibt. Wenn es keine anderen einschränkenden Kriterien gibt, die die Anzahl der Zeilen auf eine mögliche Anzahl reduzieren, wird dies zu einem starken Leistungseinbruch führen. Vielleicht möchten Sie stattdessen eine Volltextsuchlösung oder eine andere spezialisierte Lösung in Betracht ziehen.
Meinst du nicht AND col_reverse wie 'oof%' ? –
Brauchen Sie nicht 'oof%' auf col_reverse? Außerdem beantwortet das zweite Abfragefragment eine andere Frage als die erste. –
"col LIKE '% foo%'" wird die Vorkommen von "foo" überall im Feld abgleichen. "col LIKE 'foo%' ODER col_reverse LIKE 'oof%'" wird nur einer Teilmenge dieser Ergebnisse entsprechen (dh wo das Feld mit "foo" beginnt oder endet). – LukeH
Abhängig vom RDBMS, den Daten (und möglicherweise Größe der Daten), Indizes und wie der LIKE verwendet wird (mit oder ohne Präfix Wildcard)!
Sie stellen zu allgemein eine Frage.
Ja, dachte ich, aber es ist eine Frage für einen Freund, und er hat mir nicht mehr erzählt. – GhassanPL
Wenn Sie über die Auswirkungen auf die Leistung fragen:
Das Problem ist, dass es die Datenbank verwenden, einen Index hält. Auf Oracle denke ich, dass es keine Indizes mehr verwendet (aber ich bin immer noch auf Oracle 9). SqlServer verwendet Indizes, wenn sich der Platzhalter nur am Ende befindet. Ich weiß nichts über andere Datenbanken.
Direkten Zugriff auf einen Index verhindern, aber sicher nicht das Scannen eines Indexes (obwohl er möglicherweise die verwendeten Indizes ändern kann)? –
Nicht sicher, was du meinst. Den gesamten Index zu scannen (und später mit der Tabelle zu verbinden), ist nicht schneller, als die echte Tabelle zu scannen, oder? –
Das Scannen des gesamten Indexes und das anschließende Verbinden mit der Tabelle kann VIEL schneller sein als das Scannen der realen Tabelle. Indizes sind typischerweise schmaler als Tabellen und mehr "Datensätze" passen auf eine Datenbankseite. –
Bitte klären Sie, was Sie unter "Komplexität" verstehen. –
Es tut mir leid, ich fragte dies nach einem Freund, er meinte in großen O, aber das ist alles was ich weiß. – GhassanPL