Effizient in mehreren Tabellen und Spalten suchen

ElTorro

Neuer Benutzer
Beiträge
2
Guten abend allerseits,

ich habe eine Datenbank (MariaDB, InnoDB) mit Kontakten, die ich gerne mit einer InstantSuche ausstatten würde. In der Kontakte-Tabelle sollen erstmal 3 Spalten durchsucht werden: Nachname, Vorname und Firma. Da ein Kontakt mehrere E-Mail-Adressen, Telefonnummern und Anschriften haben kann, speichere ich diese Daten in 3 weiteren Tabellen, wobei in jedem Record auch die ID des Kontaktes als Fremdschlüssel gespeichert wird (1:N). Die Spalten für E-Mail-Adresse, Telefonnummer und Straße sollten möglichst ebenfalls durchsucht werden.

Die InstantSuche sollte nun bei mehreren eingegebenen Suchbegriffen nur die Kontakte anzeigen, bei denen alle eingegebenen Suchbegriffe in irgendeiner Kombination vorhanden sind. Gebe ich z.B. "martin ulrich" in das Suchfeld ein, gibt es ja diverse Möglichkeiten für die Anzeige von Ergebnissen:

"martin" in vorname und "ulrich" in nachname
"ulrich" in vorname und "martin" in nachname
"martin" und "ulrich" gemeinsam z.B. in vorname
"martin" und "ulrich" gemeinsam z.B. in nachname
"martin" und "ulrich" gemeinsam z.B. in firma
"martin" und "ulrich" gemeinsam z.B. in email

Ich habe dann mal etwas gespielt und ca. 20.000 Kontakte sowie ca. 20.000 Email-Adressen angelegt und dann folgende Abfrage erstellt, wobei lediglich 2 Kontakte tatsächlich den Bedingungen entsprechen:

SELECT Contact.id FROM contacts AS Contact left JOIN emails AS Email ON (Email.contact_id = Contact.id) WHERE ((((Contact.lastname LIKE '%martin%') OR (Contact.firstname LIKE '%martin%') OR (Contact.company LIKE '%martin%'))) AND (((Contact.lastname LIKE '%ulrich%') OR (Contact.firstname LIKE '%ulrich%') OR (Contact.company LIKE '%ulrich%'))))

Ohne die E-Mail-Adresse in den Bedingungen sieht alles gut aus - die Abfrage dauert ca. 30ms und ich erhalte als Ergebnis die gewünschten IDs der 2 Kontakte.

Dann habe ich zusätzlich die E-Mail-Adressen durchsucht:

SELECT Contact.id FROM contacts AS Contact left JOIN emails AS Email ON (Email.contact_id = Contact.id) WHERE ((((Contact.lastname LIKE '%martin%') OR (Contact.firstname LIKE '%martin%') OR (Contact.company LIKE '%martin%') OR (Email.email LIKE '%martin%'))) AND (((Contact.lastname LIKE '%ulrich%') OR (Contact.firstname LIKE '%ulrich%') OR (Contact.company LIKE '%ulrich%') OR (Email.email LIKE '%ulrich%'))))

Sobald die E-Mail-Adresse gesucht wird, benötigt die Abfrage über 2 Minuten und ist daher für meine InstantSuche ungeeignet. Wenn ich ohne Wildcard (%) arbeite, dauert die Suche immer noch deutlich über 1 Minute.

Ich habe dann noch laienhaft etwas mit Indexen herumgespielt und z.B. in der Tabelle "contacts" einen gemeinsamen FULLTEXT-Index über die Spalten "lastname", "firstname" und "company" angelegt. Zusätzlich dann noch in der Tabelle "emails" einen FULLTEXT-Index über die Spalte "email". Gebracht hat das nichts, obwohl mich das nicht wundert, da ich mit Indexen keine Erfahrung habe.

Ich stehe hier momentan etwas auf dem Schlauch und wollte fragen, ob mein Problem ein Index-Problem, ein Abfrage-Optimierungs-Problem oder ein grundsätzliches Problem mit relationalen Datenbanken und zu vielen Parameter-Kombinationen ist?

Wie könnte man in meinem Fall tabellenübergreifend nach mehreren Text-Suchbegriffen suchen und dabei eine Abfragedauer erreichen, die für eine klassische InstantSuche bzw. AutoComplete geeignet ist?

Herzlichen Dank sagt...
ElTorro
 
Zuletzt bearbeitet:
Werbung:
Nachtrag...habe gerade einen INDEX auf contact_id in der Tabelle emails gelegt und die Suche dauert jetzt 0.1 Sekunden. Ich will aber noch nicht zu früh jubeln und teste erstmal weiter.
 
Zurück
Oben