Boolsche Volltextsuche

xanthos

Mitglied
Hallo

Ich beisse mir gerade die Zähne an einer Volltextsuche aus, die meiner Ansicht nach viel zu lange dauert (2-3 Sekunden) und bin für jeden Optimierungsvorschlag sehr dankbar. Die Suche dauert erstaunlicherweise noch länger, seit ich Indizes gesetzt habe.

Code:
SELECT l.firma, COUNT( * ) as anzahl
FROM artikel a, kategorien k, kunden l
WHERE MATCH (
a.name, a.besch, k.name, l.firma
)
AGAINST (
'+test*'
IN BOOLEAN
MODE 
)
AND a.katid = k.katid
AND a.aktiv = '1'
AND a.kundenid = l.kundenid
AND l.aktiv = '1'
AND k.aktiv = '1'
GROUP BY l.firma
ORDER BY anzahl DESC , l.firma ASC 
LIMIT 0 , 30

Tabellen:
Artikel (33'000 Einträge), Fulltext auf "name" und "besch", Index auf "kundenid", "katid" und "aktiv".
Kategorien (1700 Einträge), Fulltext auf "name", Index auf "kundenid", "katid" und "aktiv".
Kunden (27 Einträge), Fulltext auf "firma", Primärschlüssel auf "kundenid", Index auf "aktiv".

Die Indizes habe ich nachträglich gesetzt, falls dies einen Einfluss hat.

Ich hoffe, Ihr könnt mir helfen, denn wenn die Suche jetzt schon 2-3 Sekunden dauert, will ich nicht wissen, wie lange sie bei 100'000 oder 1'000'000 Artikel dauert :confused:

Besten Dank.
 
Eigentlich macht ein Index das erheblich schneller.
Hast schon mal ein EXPLAIN vor die Abfrage gesetzt und geguckt ob überhaupt ein Index genutzt wird?

Desweiteren schreibe ich meine Querys immer so wie man sie auch als Mensch per Hand ausführen würde, wenn man die Tabellen vor sich liegen hat. Ist sehr oft die schnellste Variante. Das gibt dann einige Sub-Querys ;)

Vielleicht kann man bei dir an der Tabellenstruktur noch was verbessern. Vielleicht sind ja die Daten "zu sehr aufgeteilt" das dieses Zusammenfügen extrem viel Zeit braucht.
 
Hallo ZodiacXP

Vielen Dank für Deine Antwort. Explain ergab folgendes:

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE l ref PRIMARY,aktiv aktiv 1 const 11 Using where; Using temporary; Using filesort
1 SIMPLE a ref kundenid,katid,aktiv kundenid 4 tab.l.kundenid 2347 Using where
1 SIMPLE k eq_ref PRIMARY PRIMARY 4 tab.a.kundenkatid1 1 Using where

Desweiteren schreibe ich meine Querys immer so wie man sie auch als Mensch per Hand ausführen würde, wenn man die Tabellen vor sich liegen hat. Ist sehr oft die schnellste Variante. Das gibt dann einige Sub-Querys

Wie würdest Du die Struktur denn an meinem Beispiel ändern?

Besten Dank.
 
Leider erkenne ich die Struktur von deiner Abfrage nicht.
Vielleicht wenn ich den Aufbau der Tabellen sehe (SQL Export machen ;))

Aber nimm dir die Tabellen, fange an nach dem zu suchen was du suchst und schreib dir jeden winzigen Schritt auf den du per pedes machst. Daraus kann man schöne performative Querys machen.

Zudem werden keine Indizes genutzt sonst würde hinter dem USING WHERE noch ein USING index stehen

Ich empfehle dir mal diese Links:
http://phpperformance.de/mysql-datenbank-tuning/
http://phpperformance.de/indizes-richtig-einsetzen/
 
Hallo ZodiacXP

Unter possible_keys stehen die möglichen Indizes und unter key dann die verwendeten.

Ich konnte mittlerweile den "Zeitfresser" lokalisieren:

Code:
WHERE MATCH (
a.name, a.besch, ...
)

Wie ich gerade gelesen habe, ist es auch möglich, einen Index über 2 Spalten zu legen. Würde das in diesem Fall einen Sinn ergeben?

Besten Dank.
 
Habe nun einen Index für "name" und "besch" zusammen gesetzt, die Suche aufgeteilt (Artikel, Kundenkategorien, Kunden) und mit UNION verknüpft uns siehe da, das Ganze dauert noch 0,005 Sekunden :)
 

Neue Beiträge

Zurück