Einzelnen Beitrag anzeigen

nahpets
(Gast)

n/a Beiträge
 
#16

AW: Abfrage über mehrere Felder optimieren

  Alt 19. Aug 2015, 11:15
Hallo,

habe vor Jahren mal 'ne Suchmaschine (für beliebige Texte) geschrieben, die war und ist sauschnell, auch wenn sie eine Volltextsuche enthält. Das Vorgehen ist ganz einfach:

Texte werden in Einzelwörter zerlegt. Diese Wortliste wird von Dubletten bereinigt, so dass es eine eindeutige Liste wird.

Es gibt (beispielhaft) insgesamt drei Tabellen:

1. Daten : DatenID : Integer; beliebige Spalten...
2. Wortliste : WortID : Integer; Wort : varChar
3. Referenzliste: DatenID : Integer; WortID : Integer

Vorgehen:
Beim Speichern eines Satzes in der Datentabelle werden alle Felder, die im Volltextindex benötigt werden, zu einem Text zusammengedaddelt.
Dieser Text wird in Einzelwörter zerlegt.
Jedes, noch nicht in der Wortliste enthaltene, Wort wird in die Wortliste eingefügt, die Wortliste ist also eine eindeutige Liste.
Es wird die Referenzliste gepflegt. Für jedes Wort des Datensatzes wird ein Eintrag DatenID <-> WortID in die Referenzliste eingefügt.

Bei der Suche muss man dann nur (per Index) alle Sätze suchen, die zum eingegebenen Wort passen.

Das geht (beispielhaft) per:
Code:
select a.* from Daten a, Referenzliste b, Wortliste c where a.DatenID = b.DatenID and b.WortID = c.WortID and c.Wort = :Eingabe
(Selbst ein Like auf die Wortliste sollte hier nicht zum Performanzkiller werden.)

Dafür braucht man auf der Datentabelle einen Index auf der DatenID, auf der Referenztabelle einen auf DatenID und einen auf WortID und für die Worttabelle einen auf Wort.

Wenn man nun die Wortliste grundsätzlich nur in Kleinschreibweise befüllt, benötigt man für den Suchbegriff nur einmal ein Lower und spart sich die ganze Schreibweisenveränderung in jedem SQL.

Für eine schnelle Suche muss man sich die Daten nunmal normalisieren und kommt mit einer Tabelle und einem SQL ala "Liebe Datenbank, guckt doch mal, ob Du nicht eventuellunterumständenvielleicht irgendwo was passendes finden könntest" nicht aus.

Dieses sehr ungenaue "Habenmöchten" dauert einfach zu lange, wenn man nicht vorher für eine passende Struktur gesorgt hat.

Das "Wortlisteerstellen" ist (mit Delphi) sehr einfach.
Alle benötigten Felder in eine Stringliste, Delimiter auf Blank und DelimitedText abrufen. Sort aufrufen, Dubletten raus und schon kann die Wortliste in der Datenbank gepflegt werden.

Hier im Beispiel sollte die Änderung des "Systems" in ein- bis zwei Tagen in ausgereifter Form möglich sein.

Wenn man nun noch (wie oben in 'nem anderen Beitrag beschrieben) die Kölner Phonetik für die Wortliste nutzt, dann kann man damit ähnlich unscharf Suchen, wie wir es von den Suchmaschinen gewohnt sind. Meier findet dann auch Maier und Mayer und Meyer und Hofmann findet auch Hoffmann..., Cafe und Café werden nicht mehr unterschieden...

Soll der Suchbegriff mehrere Wörter enthalten (können), dann passt man das SQL halt an:
Code:
select a.* from Daten a, Referenzliste b, Wortliste c where a.DatenID = b.DatenID and b.WortID = c.WortID and c.Wort in (:Wort1, Wort2, ..., WortN)
Auf Like kann man dann ganz verzichten und kann immer per Index suchen.

Wenn das dann (mit zusätzlichem Suchkomfort) nicht schnell wird, hat man ein vollkommen anderes Problem, das nur zufällig bei der Suche deutlich aufgefallen ist.
  Mit Zitat antworten Zitat