Hallo allerseits,
ich hätte da mal eine Frage bzgl. einer indizierten Suche, die ich mit PHP + MySQL 5 implementiert hab:
Ich habe 3 Tabellen:
1. documents (id, text)
Diese Tabelle enthält Text-Dokumente (ca. 300.000). Sie werden indiziert und die Wörter werden in folgender Tabelle abgelegt:
2. mywords(id, word)
Sie enthält ca 150.000 Begriffe.
3. myindex (doc_id, word_id)
Diese Tabelle enthält die Zuordnung der Wörter aus der mywords-Tabelle zu den Dokumenten in der documents-Tabelle. Sie stellt also meinen Suchindex dar und enthält ca 5 Millionen Einträge.
Wenn ich jetzt ein Document suchen will anhand eines Begriffes, könnte ich z.B. folgendes machen:
Durch die Verwendeten Primary Keys/Indizes ist das auch schön schnell. Die Antwort kommt im 0,000X-Sekunden-Bereich.
Mein Problem ist jetzt, wie ich es schaffe die Suche durch weitere Suchwörter einzuschränken, ohne, dass die Geschwindikeit stark drunter leidet. Mein erster Versuch waren weitere Joins, z.B.:
Für 2 Suchwörter hat die Suche noch 2 Sekunden gedauert, bei den 3 Wörtern schon 35 Sekunden (... auch wenn PMA etwas anderes anzeigt) und die CPU war komplett ausgelastet.
Meine nächste Idee ging in Richtung verschachtelter Abfragen:
Für die 3 Suchworte komme ich damit auf ca. 3 Sekunden Suchzeit, was auch noch nicht wirklich prickelnd ist.
Mit EXISTS dauert die Suche auch ein paar Sekunden:
Mit folgender Suche läuft es bisher am schnellsten:
Damit komme ich auf jeden Fall unter eine Sekunde, wenn mySQL schon ein bisschen gecached hat.
Jetzt meine Frage: Habt ihr noch weitere Ideen für die Such-Queries? Also wie man das ganze noch beschleunigen könnte?
Gruss,
M_Kay
ich hätte da mal eine Frage bzgl. einer indizierten Suche, die ich mit PHP + MySQL 5 implementiert hab:
Ich habe 3 Tabellen:
1. documents (id, text)
Diese Tabelle enthält Text-Dokumente (ca. 300.000). Sie werden indiziert und die Wörter werden in folgender Tabelle abgelegt:
2. mywords(id, word)
Sie enthält ca 150.000 Begriffe.
3. myindex (doc_id, word_id)
Diese Tabelle enthält die Zuordnung der Wörter aus der mywords-Tabelle zu den Dokumenten in der documents-Tabelle. Sie stellt also meinen Suchindex dar und enthält ca 5 Millionen Einträge.
Wenn ich jetzt ein Document suchen will anhand eines Begriffes, könnte ich z.B. folgendes machen:
Code:
SELECT `myindex`.doc_id
FROM mywords
JOIN `myindex` ON `myindex`.word_id = mywords.id
WHERE mywords.word LIKE 'emmi%'
Mein Problem ist jetzt, wie ich es schaffe die Suche durch weitere Suchwörter einzuschränken, ohne, dass die Geschwindikeit stark drunter leidet. Mein erster Versuch waren weitere Joins, z.B.:
Code:
SELECT `myindex`.doc_id
FROM mywords AS words1
JOIN `myindex` ON `myindex`.word_id = words1.id
JOIN mywords AS words2
JOIN `myindex` AS index2 ON index2.word_id = words2.id
JOIN mywords AS words3
JOIN `myindex` AS index3 ON index3.word_id = words3.id
WHERE 1
AND words1.word LIKE 'emmi%'
AND words2.word LIKE 'sam%'
AND words3.word LIKE 'bree%'
AND `myindex`.doc_id = index2.doc_id
AND `myindex`.doc_id = index3.doc_id
Meine nächste Idee ging in Richtung verschachtelter Abfragen:
Code:
SELECT `myindex`.doc_id
FROM
(
SELECT `myindex`.doc_id
FROM
(
SELECT `myindex`.doc_id
FROM mywords
JOIN `myindex` ON `myindex`.word_id = mywords.id
WHERE mywords.word LIKE 'emmi%'
) AS results1
JOIN `myindex` ON `myindex`.doc_id = results1.doc_id
JOIN mywords ON `myindex`.word_id = mywords.id
WHERE mywords.word LIKE 'sam%'
) AS results2
JOIN `myindex` ON `myindex`.doc_id = results2.doc_id
JOIN mywords ON `myindex`.word_id = mywords.id
WHERE mywords.word LIKE 'bree%'
Mit EXISTS dauert die Suche auch ein paar Sekunden:
Code:
SELECT *
FROM `myindex` AS in2
JOIN mywords AS wo2 ON in2.word_id = wo2.id
WHERE 1
AND wo2.word LIKE 'emmi%'
AND EXISTS
(
SELECT *
FROM `myindex` AS in1
JOIN mywords AS wo1 ON in1.word_id = wo1.id
WHERE 1
AND in1.doc_id = in2.doc_id
AND wo1.word LIKE 'sam%'
)
AND EXISTS
(
SELECT *
FROM `myindex` AS in1
JOIN mywords AS wo1 ON in1.word_id = wo1.id
WHERE 1
AND in1.doc_id = in2.doc_id
AND wo1.word LIKE 'bree%'
)
Mit folgender Suche läuft es bisher am schnellsten:
Code:
SELECT `myindex`.doc_id
FROM mywords
JOIN `myindex` ON `myindex`.word_id = mywords.id
WHERE
(
mywords.word LIKE 'emmi%' OR
mywords.word LIKE 'sam%' OR
mywords.word LIKE 'bree%'
)
GROUP BY `myindex`.doc_id HAVING COUNT( word_id )=3
Jetzt meine Frage: Habt ihr noch weitere Ideen für die Such-Queries? Also wie man das ganze noch beschleunigen könnte?
Gruss,
M_Kay
Zuletzt bearbeitet: