Grafzahl wrote:So, hier ist der Dump der Tabelle Artikel:
Code: Select all
CREATE TABLE `Artikel` (
`Shopnum` int(11) NOT NULL default '0',
`Titel` varchar(50) NOT NULL default '',
`Stop` int(11) NOT NULL default '0',
`Preis` decimal(11,2) NOT NULL default '0.00',
`Gebote` int(4) NOT NULL default '0',
`URL` varchar(100) NOT NULL default '',
`BildURL` varchar(100) NOT NULL default '',
KEY `Titel` (`Titel`)
) TYPE=MyISAM;
Kein Index, deshalb jedes mal ein Tablescan.
und hier eine Abfrage aus der "Schnellsuche" mit dem Begriff "Test":
Code: Select all
SELECT Artikel.Titel,Artikel.Stop,Artikel.Preis,Artikel.Gebote,Artikel.URL,Shop.Shopname FROM Artikel,Shop WHERE Artikel.Stop > 1086624990 AND Artikel.Shopnum = Shop.shNummer AND (Titel LIKE '% test %' OR Titel LIKE 'test %' OR Titel LIKE '% test') ORDER BY Artikel.Stop LIMIT 0,50
Zur Info: shNummer ist in der Tabelle Shops PRIMARY KEY
Erstmal readability: ;)
select a.titel, a.top, a.preis, a.gebote, a.url from artikel a where bla bla bla
Der join passt, aber Index für beide angeben... wenn du immer über stop gehst, auch
nen Index drauf, dann brauchst du den auf a.shopnum evtl. nicht mehr.
Dann die Suche... '%irgendwas' ist immer böse, da Tablescan, der Optimizer kann sowas
nicht verarbeiten. 'irgendwas%' kann der Optimizer verarbeiten, die anderen Kombinationen nicht. Brauchst du die Leerzeichen vor und nach "test" wirklich?
Wenn du das Produktiv nutzst wird dir auch eine Sybase oder Oracle ziemlich schnell
abkacken.
@OutofBound:
Die Querries sieht man nur wenn man gerade eine offene Anfrage erwischt. Die DB ist nicht unten gewesen.
Ja, ich hatte gehofft ein paar aktive Querries zu sehen, die Live verwendet werden.
Logs sind abgeschaltet. Eigentlich mache ich auf diese Tabelle nur ein Querry bei der Suchanfrage. Zwischendurch wird aber mal ein oder zwei COUNT(*) als Information zur Artikelanzahl gefragt.
Das mit dem joinen klingt zwar nett ist aber nicht realisierbar. Wenn jemand z.B. Ixus eingibt sollen alle Artikel nach Preis sortiert kommen die auch "Ixus" als eigenständiges Wort beinhalten.
Ã?ehm, sowas geht durchaus. Kann man über m-n Beziehungen lösen mit
Schlagwort- Indices.
Mit den JOINS hatte ich mal in umgekehrter Methode probiert. Ich wollte alle Shops listen mit deren Anzahl von Artikeln.
Code: Select all
SELECT Shopname,COUNT(*) FROM Shop LEFT JOIN (Shop.shNummer = Artikel.Shopnum) ON Artikel GROUP BY Shopname
select s.shopname, count(*) from shop s, artikel a where s.shNummer = a.Shopnum group by s.shopname
Wenn das zu lange dauert, dann fehlen Indices.
Das hat ewig gedauert und ich habe es umfunktioniert. Nun wird beim nächtlichen Artikelimport die Artikel mittel $i++ gezählt und in die Tabelle zum entspechenden Shop geupdated.
Setz ein paar Indices, wirf das Mitzählen weg und mach einen schlagwortindex, dann
sollte dein Problem gelöst sein. D
Bsp:
Tbl. words
[id] Numeric[10]
[word] varchar[50]
Tbl artikelmatrix
[artikelid] Numeric[10]
[wordid] Numeric[10]
Tbl.
artikel
[id] Numeric [10]
[beschreibung] varchar[100]
[etc]
Und dann ein select * from words w, artikelmatrix m, artikel a where w.id = m.wordid and m.artikelid = a.id and w.word like 'luxus'
Beim einfügen von Artikeln splittest du die Beschreibung und trägst die Wörter die noch nicht vorhanden sind in die Tbl. words ein, wenn schon vorhanden nutzt du die ID davon. Dann trägst du die Artikel in die artikelmatrix mit den Wörtern ein, fertig.
Beim austragen von Artikeln dann einfach ein delete from artikelmatrix where artikelid = bla machen und das Ding ist aus der Suche ausgetragen.
Da würde ich dann Indices auf die beiden artikelmatrix IDs legen, und auf artikel.id und words.id, und dann wirste staunen wie schnell das rödelt. ;)
Wenn es wirklich viele Wörter sind, kannst du evtl. noch nen Index auf die eigentlichen
Wörter in words legen, aber ich denke das ist aber nur durch messen zu beurteilen.
Gruss,
Out
PS: Alles in Allem: Hab ichs nicht gesagt? ;) ;)
PPS: Nur grad so ausm Kopf zusammengeschludert, man muss natürlich noch einiges mehr
beachten. Datenbankdesign ist sowohl Können als auch Kunst, deshalb muss jede Lösung
individuell betrachtet werden. Ich wollte nur nachweisen, dass man Wörtersuchen noch wesentlich effizienter gestalten kann als mit '%irgendwas%'.