PDA

View Full Version : sql like



ILEMax
13-12-16, 08:13
Hallo *all

In einer Datei gibt es ein Feld: Feld.
Es hat u.a. diese Inhalte (rd 700.000 Sätze, index vorhanden)

123456789
0123456789
00123456789
123456789000

Wenn ich ein
select * from datei where feld like '%123456789%'
mache bekomme ich alle Sätze angezeigt. (< 2 Sekunden)

Wenn ich ein
select * from datei where feld like '%123456789'
mache hätte ich mir die ersten 3 Sätze erhofft.
Es kommt aber nix. ( < 2 Sekunden)

mache ich
select * from datei where trim(feld) like '%123456789'
Warte ich 35 Sekunden bis zu einer Anzeige

kann ich dem 'LIKE' noch anders sagen, das Leerzeichen am ende ok sind?

Danke
Der ILEMax

B.Hauser
13-12-16, 08:20
FELD ist mit fixer Länge definiert, deshalb bekommt er bei 1. alle Felder und bei 2. keine Felder. Im 3. Fall müssen von FELD alle führenden und folgenden Blanks entfernt werden, bevor der Vergleich erfolgen kann und das kostet Zeit.

Mögliche Verbesserungen:
1. Satt TRIM RTRIM verwenden
2. 2 Like Anweisungen mit OR verknüpfen:
2.1. LIKE '%123456789%'
2.2. LIKE '%123456789 %'

Birgitta

ILEMax
13-12-16, 09:19
Hallo Birgitta,

ja, like '%123456789 %' geht!

Leider ist das nur 'meistens' richtig.

ein '123456789 555' würde aber auch gefunden und angezeigt.
Ich mach es jetzt mit dem zusätzlichen ' %' und überlese die Sätze die mit (z.B.) ' 555' gefunden werden.
kommt G.s.D nicht so oft vor.

Danke
der ILEMax

Fuerchau
13-12-16, 09:30
Die Erklärung ist nur halbherzig:
Bei "%xxx%" erfolgt im Prinzip ein Scan über das Feld.
Bei "%XXX" muss der Inhalt des Feldes mit diesem Wert aufhören (also rechtsbündig). Da dein Feld sicher nicht vom Typ Varying ist, hast du halt noch Leerzeichen hinter dem Inhalt und somit Endet das Feld nicht mit der Suchfolge.
Bei "%1.... %" muss ein Leerzeichen im Feld hinter dem Suchbegriff sein, sollte der Inhalt rechtsbündig stehen, wird er nicht gefunden.
Kommen wir zur Performance.
Liegt über FELD ein Index, kann SQL ggf. einen Index-Only-Zugriff machen und somit erheblich schneller einen Tablescan durchführen.
Mit der Funktion "trim(FELD)" kann der Index nicht benutzt werden, was dann zu einem tatsächlichen Tablescan führt. Dies kann man ggf. mit einem "calculated Index" wiederum beschleunigen.

Übrigens kann man auch den Tablescan ein wenig beschleunigen, wenn man möglichst wenig gelöschte Sätze in der Tabelle hat, deshalb haben TABLE-Objekte auch default REUSEDLT(*YES), denn das überlesen von gelöschtgen Sätzen mangels Index kostet auch Zeit.