Performante SQL- Abfrage (LIKE %)

Generic1

Top Contributor
Hallo,

"fassy" hat mir mal bei einem Thread folgendes geschrieben:

>> '%Hans%'
>> ist immer eine ganz schlechte Idee. Wenn du das Pattern mit einem Wildcard anfängst kann die >> Datenbank keine Indexstrukturen nutzen und macht einen Fulltablescan - sprich die Performance >> geht in den Keller.

Ich brauche aber eine Abfrage in der abgefragt wird, ob z.B. ein Vorname Hans enthält.
Wie würdet ihr dann das machen?

Meine Abfrage schaut momentan so aus:

Java:
public List<Participant> searchParticipant(final String name) {
            final String searchQuery = " from " + PARTICIPANT + " as p where p.firstname LIKE '%" + name + 
                                       "%' OR p.surname LIKE '%" + name +
                                       "%' OR p.address.city LIKE '%" + name + 
                                       "%' OR p.club.clubname LIKE '%" + name + "%')";
            return getHibernateTemplate().find(searchQuery);
            }

Vielen Dank und lg
 
Zuletzt bearbeitet von einem Moderator:

The_S

Top Contributor
Naja, wenn "Hans" nunmal irgendwo auftreten kann, dann musste auch so suchen. Alternativ kannste auch nach allen suchen, die mit Hans Anfangen und dann selbst die Liste noch filtern - ob das aber so performanter ist, wage ich zu bezweifeln. Hast du denn Performanceprobleme?

Außerdem solltest du deinen SQL nicht mit + zusammenbauen, sondern Parameter über die entsprechenden Methoden der Query (!?, habe Hibernate jetzt schon lange nicht mehr verwendet) Klasse setzen.
 

ARadauer

Top Contributor
Performance >> geht in den Keller.
ist relativ... was will man den machen? gewisse dinge dauern halt.

Indizes sind manchmal eine Lösung. Leg mal einen Index über die Spalte und schau ob dir das was bring und ob die einfüge Zeiten nicht zu hoch werden.
Alternativ könnte mannoch eine externes System für die Suche verwenden zb lucene, die frage ist halt ob das nicht zu viel ist...
 

Generic1

Top Contributor
Also momentan hab ich keine Performance- Probleme, der Kommentar von fassy hat mich aber zum Nachdenken gebracht.

Weiß jemand wie das geht mit einer Hibernate- Query, dass ich dort wo Parameter hinkommen ein ? setzt und mit einer Parameterliste ausfülle?

Code:
public List<Participant> searchParticipant(final String name) {
            final String searchQuery = " from " + PARTICIPANT + " as p where p.firstname LIKE '%" + name + 
                                       "%' OR p.surname LIKE '%" + name +
                                       "%' OR p.address.city LIKE '%" + name + 
                                       "%' OR p.club.clubname LIKE '%" + name + "%')";
            return getHibernateTemplate().find(searchQuery);
            }
 
M

Marcinek

Gast
Diese nennt man Hostvariablen

Es ist mit hibernate auch möglich Textmarken zu setzten.

where name = :name

Dann kann man aus dem SQL String ein SQLQuery erzeugen und mit

setPropertie ("name", object) ersetzten.

Ich würde in suchen niemans hardcoded % im präfix benutzen, da du daruch keine indizes ausnutzen kannst.

Lass das den User mit wildcards selbst bestimmen...

In unseren Anwendungen wird führendes * garnicht für das Suchen erlaubt.
 
G

Gast2

Gast
Das Problem ist das du eine "Volltext" Suche machen willst. Das ist in Datenbanken normalerweise keine gute Sache, dafür sind relationale Modelle nicht geeignet. Normalerweise würd ich dein Problem so lösen:

Code:
FirstName                | LastName | some other columns
--------------------------------------------------------
Klaus-Hans-Dieter        | Schulz   | ...

Diese Tabelle aufteilen in entweder:
Code:
FirstName | MiddleName1 | MiddleName2 | LastName | some other columns
---------------------------------------------------------------------
Klaus     | Hans        | Dieter      | Schulz   | ...

Oder evtl noch normalisieren und eine Tabelle mit möglichen Vornamen sammeln.

Dann im Query:
SQL:
WHERE (FirstName = 'Hans' OR MiddleName1 = 'Hans' OR MiddleName2 = 'Hans')

So kann due Datenbank mögliche Indexe und Optimierung voll ausnutzen.
 
Zuletzt bearbeitet von einem Moderator:

KSG9|sebastian

Top Contributor
Man sollte das schon je nach Anwendung unterscheiden.

Für eine kleine App mit ein paar hundert Zeilen in der Tabelle ist es völlig egal. Meistens ist es da sogar günstiger ohne Indizes zu arbeiten (siehe Problematik beim Update/Insert). Einige Datenbanken machen bei so kleinen Datenmengen sowieso einen Fulltablescan.

Selbst bei ein paar tausend Sätzen dürfte das nicht ins Gewicht fallen.

Somit sollte erst mal geklärt werden von welchen Datenmengen wir da reden...
 
G

Gast2

Gast
Man sollte das schon je nach Anwendung unterscheiden.

Für eine kleine App mit ein paar hundert Zeilen in der Tabelle ist es völlig egal. Meistens ist es da sogar günstiger ohne Indizes zu arbeiten (siehe Problematik beim Update/Insert). Einige Datenbanken machen bei so kleinen Datenmengen sowieso einen Fulltablescan.

Selbst bei ein paar tausend Sätzen dürfte das nicht ins Gewicht fallen.

Somit sollte erst mal geklärt werden von welchen Datenmengen wir da reden...

Da geb ich dir recht - aber oftmals ist es so das Leute grade in der Ausbildung oder im Studium mit kleinen überschaubaren Szenarien arbeiten und sich keine weitere Gedanken machen. Später wird das dann 1:1 auf large-scale Enterprise Systeme übertragen. Ich hab schon sehr viele große Datenbanken gesehn wo jemand mit [c]LIKE '%XYZ'[/c] drauf losgegangen ist und sich wunderte das die Queries eine Stunde hängen. Was wurde gemacht? Richtig - neue stärkere Hardware gekauft anstatt einmal den Query Execution / Explain Plan anzugucken ;)
 

fastjack

Top Contributor
1. Möglichkeit die mir einfällt:

Probier doch mal aus, alle Spalten die durchsucht werden sollen, zu konkatenieren (CONCAT....) und dann ein einziges Like anzuwenden.

MySQL ungefähr so:

select a, b, c, concat(a, b, c) as search from d where search like '%Hans%'

Es kann sein, das Du ein wenig casten oder konvertieren mußt, ich kenne Suchen, die so recht schnell arbeiten, auch bei größeren Datenbeständen.

2. Möglichkeit:

Baue ein spezielles Suchfeld in die Tabelle ein, daß beim Schreiben direkt mit konkatenierten Daten anderer Suchspalten mitgeschrieben wird. Also z.B.

Tabelle X,
Spalten a, b, c
+ spezielle Suchspalte search

bei Inserts/Updates wird die Suchspalte mit a, b, c gefüttert

--> select a, b, c from X where search like '%Hans%';
 

tfa

Top Contributor
Bevor man wild drauf los frickelt, sollte man sich eine bewährte Lösung ansehen. Das Zauberwort hat ARadauer doch schon gesagt: lucene.
Ansonsten bin ich der Meinung, dass man Probleme, die man (noch) gar nicht hat, auch nicht zu lösen versuchen sollte. Das gilt insbesondere für Performance-Optimierung.
 

KSG9|sebastian

Top Contributor
Da geb ich dir recht - aber oftmals ist es so das Leute grade in der Ausbildung oder im Studium mit kleinen überschaubaren Szenarien arbeiten und sich keine weitere Gedanken machen. Später wird das dann 1:1 auf large-scale Enterprise Systeme übertragen. Ich hab schon sehr viele große Datenbanken gesehn wo jemand mit [c]LIKE '%XYZ'[/c] drauf losgegangen ist und sich wunderte das die Queries eine Stunde hängen. Was wurde gemacht? Richtig - neue stärkere Hardware gekauft anstatt einmal den Query Execution / Explain Plan anzugucken ;)

Hi,

die Probleme kenne ich auch. Man sollte sich schon Gedanken machen und auch im Hinterkopf behalten das solche Lösungen eben nicht skalieren und der DB-Admin einem den Kopf abreist wenn er nen Explainplan anschaut. :)
 
J

JohannisderKaeufer

Gast
1. Möglichkeit die mir einfällt:

Probier doch mal aus, alle Spalten die durchsucht werden sollen, zu konkatenieren (CONCAT....) und dann ein einziges Like anzuwenden.

MySQL ungefähr so:

select a, b, c, concat(a, b, c) as search from d where search like '%Hans%'

Es kann sein, das Du ein wenig casten oder konvertieren mußt, ich kenne Suchen, die so recht schnell arbeiten, auch bei größeren Datenbeständen.

Könnte das dann nicht auch einen Johan Schulz, als joHANSchulz liefern. Obwohl das eigentlich nichts mehr mit Hans zu tun hat.
 

fastjack

Top Contributor
Das kann durchaus sein, hast Du Dir mal den Queryaufbau von generic angesehen? Aber ich glaube ob die Prozentzeichen jetzt so sind oder anders, das sollte dem Beispiel latte sein, es geht nur um den Aufbau.
 
S

SlaterB

Gast
> Könnte das dann nicht auch einen Johan Schulz, als joHANSchulz liefern.

Leerzeichen beim concat() einfügen, falls das eine Frage und nicht nur ein Hinweis war
 
M

Marcinek

Gast
Ja klar.

MYSQL mit dem entsprechenden Zeichencodierung für einen varchar Feld. Müsste ich jetzt bei schauen.

Da wir in neuen Projekten mittlerweise spezielle Felder zur ablage von Suchstrings haben, kann ich garnicht aus dem Kopf sagen, wie sich Informix oder DB2 verhällt.
 
J

JohannisderKaeufer

Gast
Ob Casesensitive oder nicht ist ja egal.
Gerade bei Suchanfragen die Benutzer eingeben, stellt man oft selbst Suchstring und das zu vergleichende Objekt auf lowercase oder uppercase um eine Casesensitivität zu vermeiden.
Das ist hier zwar noch nicht der Fall, kann aber schon im nächsten Schritt hinzukommen.

Das mit dem concat und dem Beispiel, habe ich eigentlich nur eingebracht, um zu verdeutlichen das das auch ganz unerwartete Auswirkungen haben kann.


BTW. gibt es auch "Ähnlichkeitssuchen", weiß aber nicht mehr wie das genau heißt. Sucht man damit nach Meier werden auch Meir, Mair, Maier, Mayer, Meyer, Meyr, Mayr etc. gefunden. Das geht dann schon über die Frage der Casesensitivität hinaus.
 
G

Gast2

Gast
Soweit ich den Usecase verstanden habe, geht es darum, Teilnamen zu finden. Mein Ansatz wäre folgender (vorausgesetzt die Datenmenge ist gross genug, um dies zu rechtfertigen und der Name besitzt klare Delimiter wie "-" oder " "):

neben der Usertabelle existiert eine Lookup-Tabelle:
id, lookup_name, id_user
...lookup_name ist indiziert und id_user ein Fremdschlüssel der Usertabelle.

Mit einem after_insert trigger auf der Usertabelle, könnte man den Usernamen in seine logischen Teilstrings zerlegen und für jeden einen Lookup-Entry generieren vordefiniert in upper oder lower case.

Das ganze macht natürlich nur Sinn bei entsprechend vielen Datensätzen und einer sehr häufig ausgeführten Abfrage, die vom Muster auch nicht abweicht. Sobald man hier wieder in die Verlegung kommt, mit LIKE abzufragen, wird dies noch unperformanter, da zu jedem User-Eintrag mindestens ein Lookup-Eintrag exisiteren würde.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
B Wie kann ich eine Jtable mit Inhalt einer SQL Abfrage füllen Datenbankprogrammierung 14
J SQLite Abfrage fehlerhaft - komme nicht weiter - please help. Datenbankprogrammierung 3
L PostgreSQL Abfrage mit EclipseLink Datenbankprogrammierung 7
S Berechnung des Datumsunterschieds in der SQL-Abfrage Datenbankprogrammierung 1
Zrebna Probleme bei Überführung von SQL-Code in eine HQL-Abfrage Datenbankprogrammierung 3
btwX28 mysql abfrage über phpmyadmin Datenbankprogrammierung 8
M Alle Records Felder kriegen für DB Abfrage Datenbankprogrammierung 14
pkm PostgreSQL Kann mit mybatis einen Parameter für eine postgreSQL-Abfrage nicht übergeben. Datenbankprogrammierung 5
nonickatall MySQL SQL Abfrage erneut ausführen oder rs aktualisieren Datenbankprogrammierung 14
Kirby.exe Verständnisproblem bei SQL Abfrage Datenbankprogrammierung 27
N SQL-Abfrage in JTextField ausgeben Datenbankprogrammierung 6
N java sql abfrage bestimmer Datumszeitraum Datenbankprogrammierung 9
F Mapping einer SQL Abfrage in eine Klasse Datenbankprogrammierung 4
N Java Abfrage über GUI, Daten hinzufügen Datenbankprogrammierung 54
Bluedaishi Datenbank Abfrage Datenbankprogrammierung 36
W MySQL DB Abfrage in Array, gemischte Array, generelles vorgehen Datenbankprogrammierung 4
D SQL Abfrage optimieren Datenbankprogrammierung 35
D MySQL Abfrage Datenbankprogrammierung 5
D MySQL Abfrage sortieren Datenbankprogrammierung 4
D MySQL Abfrage SUM datediff Datenbankprogrammierung 3
D Regelmäßige Abfrage aus Workbench Datenbankprogrammierung 6
M SQL-Statement Hilfe bei SQL-Abfrage Datenbankprogrammierung 2
D Abfrage - Spalte(Datum) ändern (Oracle) Datenbankprogrammierung 7
D Datenbank Abfrage Datenbankprogrammierung 7
H MySQL Benutzer Login System mit Datenbank Informationen (Abfrage zu User ist auf DB gesichert) Datenbankprogrammierung 42
D MySQL Abfrage mit kumulierten Werten Datenbankprogrammierung 16
M MySQL Anbindung und Abfrage an die Datenbank Datenbankprogrammierung 2
RowdyN SQLite Einfache Abfrage mit temporäre Tabelle, die nur innerhalb der Abfrage gültig ist Datenbankprogrammierung 0
E Abfrage auf HSQLDB Datenbankprogrammierung 4
M MySQL SQL Abfrage in JTable mit Berechnung Datenbankprogrammierung 3
S Abfrage von Gruppentickets(Mehrere Resorts an einem Tag) Datenbankprogrammierung 1
S SQL Abfrage Datenbankprogrammierung 2
F Abfrage der letzten Einträge Datenbankprogrammierung 2
J SELECT Abfrage/Suche Datenbankprogrammierung 4
U SQLite Für mich etwa komplexe Abfrage via 2 Tabellen Datenbankprogrammierung 5
OnDemand SQL Abfrage und Equals Datenbankprogrammierung 4
B MySQL MySQL-Abfrage von aufsummierter Zeit Datenbankprogrammierung 3
M MySQL MySQLSyntaxError in Java, obwohl Abfrage in HeidiSQL korrekt Datenbankprogrammierung 2
ruutaiokwu sql abfrage mit rekursion, mit oder ohne cte... Datenbankprogrammierung 5
J SQLite Abfrage ausführen stoppt für Zyklus? Wie es zu lösen? Datenbankprogrammierung 3
L JSONArray/JSONObject MySQL-Servlet Abfrage Datenbankprogrammierung 2
H Derby: SYSCS_UTIL.SYSCS_EXPORT_QUERY mit String Abfrage in wehre-Klausel nicht möglich Datenbankprogrammierung 3
L SQL-Abfrage bricht vor dem Ende ab Datenbankprogrammierung 2
S MySQL Abfrage über mehrere Tabellen + Einträge werden überschrieben Datenbankprogrammierung 1
M Derby/JavaDB Komplexe Abfrage vereinfachen Datenbankprogrammierung 2
S SQL-Abfrage, Filewriter .txt Datei Datenbankprogrammierung 2
P Datenbank- Abfrage mit null'en Datenbankprogrammierung 2
Bluedaishi MySQL Abfrage Problem :-) Datenbankprogrammierung 21
D MySQL Erstellen der richtigen Abfrage Datenbankprogrammierung 3
D MySQL DB Abfrage Prüfen Datenbankprogrammierung 10
D JDBC insert mit select abfrage Datenbankprogrammierung 5
E PostgreSQL Exception too ...many clients already bei DB-Abfrage Datenbankprogrammierung 14
M MySQL SQL Abfrage Problem Datenbankprogrammierung 6
W No data found: SQL-Abfrage funktioniert nur beim Debuggen Datenbankprogrammierung 3
E Abfrage nach existierender SQL-Tabelle Datenbankprogrammierung 7
H JSON Array abfrage beschleunigen Datenbankprogrammierung 2
S MySQL Abfrage: Wenn Feld leer, alles anzeigen Datenbankprogrammierung 5
Mrtwomoon Abfrage-Ergebnisse in einem Fenster darstellen Datenbankprogrammierung 8
0 SQL Abfrage Bestellung Datenbankprogrammierung 15
G SQLite SQLite Abfrage Datenbankprogrammierung 4
C Mit jsp über Java eine DB Abfrage durchführen --> java.lang.ClassNotFoundException Datenbankprogrammierung 4
Dit_ Hibernate, effiziente SQL-Abfrage definieren Datenbankprogrammierung 5
B My-SQL Abfrage - Out Of Memory Error Datenbankprogrammierung 13
C MySQL Problem mit UPDATE Abfrage Datenbankprogrammierung 13
K SQLite Einfache DB-Abfrage Datenbankprogrammierung 2
C Problem mit SQL-Abfrage Datenbankprogrammierung 5
C Sortierung bei SQL-Abfrage Datenbankprogrammierung 3
B Bei Abfrage schießt der Speicher in die Höhe Datenbankprogrammierung 6
M SQL Abfrage Dupliakte bei Kreuzvergleich Datenbankprogrammierung 2
M Access Abfrage mit Parameter & Access/Java liefern unterschiedliche Ergebnisse Datenbankprogrammierung 2
G SQL Abfrage Datenbankprogrammierung 5
C SQL-Abfrage Datenbankprogrammierung 4
B SQL-Abfrage Datenbankprogrammierung 4
R SQL Abfrage, je nach ausgewählten Parametern Datenbankprogrammierung 11
C Wert in SQL-Abfrage zählen lassen Datenbankprogrammierung 8
R Memory leaks bei DB Abfrage Datenbankprogrammierung 16
S Abfrage auf SQLite-DB Datenbankprogrammierung 2
I Belastet es das System zu sehr einen Timer jede 0.2 Sekunden eine DB Abfrage machen zu lassen? Datenbankprogrammierung 9
L MySQL Probleme mit PreparedStatement für SQL-Abfrage in Java Datenbankprogrammierung 2
G Abfrage von Teilnehmern Datenbankprogrammierung 4
B HSQLDB Probleme mit Select...Where Abfrage Datenbankprogrammierung 16
G JOIN Abfrage über mehrere Tabellen Datenbankprogrammierung 15
F MySQL SQL Abfrage für u.a. Spaltenname key Datenbankprogrammierung 4
G SQLite Abfrage, ob in Tabelle X Spalte Y existiert Datenbankprogrammierung 4
A MySQL Ergebnss aus SQL Abfrage in Hauptklasse verwenden Datenbankprogrammierung 3
N Geschwindigkeit bei if Abfrage Datenbankprogrammierung 11
J sql abfrage ... Problem mit Datumswert Datenbankprogrammierung 3
G Join Abfrage Datenbankprogrammierung 12
M db abfrage fehlerhaft Datenbankprogrammierung 5
C MySQL Abfrage mit flexibler WHERE bedingung Datenbankprogrammierung 10
C Datenbank-Abfrage, if im Select Datenbankprogrammierung 9
S MySQL Frage zu LeftJoin Abfrage Datenbankprogrammierung 2
G SQL Abfrage über mehrere Tabellen Datenbankprogrammierung 28
H SQL Abfrage - zwei tabellen vergleichen. Datenbankprogrammierung 2
H MySQL Datenbank Abfrage Datenbankprogrammierung 10
André Uhres SQL Abfrage erkennt keine Buchstaben mit Akzenten (z. B. é, è) Datenbankprogrammierung 3
E MySQL Klasse zur Abfrage statisch oder Standard Datenbankprogrammierung 5
J Mit einer Abfrage Worte suchen die in Zwei Tabellen enthalten sind Datenbankprogrammierung 5
G M:N Abfrage Datenbankprogrammierung 2
J where Abfrage auf ein mysql date feld Datenbankprogrammierung 5

Ähnliche Java Themen

Neue Themen


Oben