chris-u
Goto Top

MySQL-Abfrage sehr langsam (Faktor 300)

MySQL Abfrage sehr langsam sobald in 2 verknüpften Tabellen gesucht wird.

Habe 2 Tabellen A und B. Die Datensätze lassen sich über eine ID verknüpfen. In beiden Tabellen soll je ein Feld nach einem string durchsucht werden.
Meine SQL-Abfrage sieht so aus:


SELECT `name` , `B`.`WERT2`
FROM `A`
LEFT JOIN `B` ON `A`.`id` = `B`.`id`
WHERE `A`.`name` LIKE '%test3%'
OR `B`.`WERT2` LIKE '%test3%'


In den Tabellen sind jeweils 1600 Datensätze. Die Abfrage dauert 7,8 Sekunden!!!!!!
Sobald ich die Prüfung
"OR `B`.`WERT2` LIKE '%test3%'"
weg lasse ist die abfrage 300mal so schnell fertig (0,026 sek) wie mit der zusätzlichen abfrage.
auch wenn ich den ersten teil der WHERE Abfrage weg lasse, also den Teil:
"`A`.`name` LIKE '%test3%' "
ist es ca. 300mal schneller als mit beiden Abprüfungen.

Hat jemand ne Idee, wie ich die Abfrage mit beiden Abprüfungen performanter hin bekommen kann?


Vielen dank schonmal!

Gruß,
Christopher

Content-ID: 100345

Url: https://administrator.de/contentid/100345

Ausgedruckt am: 22.11.2024 um 20:11 Uhr

Biber
Biber 27.10.2008 um 15:35:22 Uhr
Goto Top
Moin Chris-U,

Hat jemand ne Idee, wie ich die Abfrage mit beiden Abprüfungen performanter hin bekommen kann?
Idee 1: Redesign.
kann doch wohl nicht sein, dass ein Suchwert mal in "A.Name" und mal in "B.Wert2" stehen darf..
Aber das wolltest Du wahrscheinlich nicht wissen...

Idee 2
SELECT 'A'.`name` , `B`.`WERT2`  
FROM `A` 
LEFT JOIN `B` ON `A`.`id` = `B`.`id` 
WHERE `A`.`name`|| B.Wert2 LIKE '%test3%'   

Grüße
Biber
Chris-U
Chris-U 27.10.2008 um 16:55:52 Uhr
Goto Top
Hi und danke für die schnelle Antwort!

Idee 1 geht leider nicht. Es handelt sich bei der Abfrage um eine Suchfunktion in einem Onlineshop wo mehrere Felder vom Artikelstamm geprüft werden müssen, z.b. Art-Nr Art-Bezeichnung, Beschreibung usw... Habe den Beispielcode oben stark vereinfacht und in der Form auch getsetet.

Idee 2 habe ich probiert, leider kein Erfolg, ist genauso langsam wie vorher.
Problem besteht wohl, wenn ich in 2 versch Tabellen suche.

Vllt gibts ja noch ein paar gute Vorschläge!

Schönen Feierabend!

Christopher
Biber
Biber 27.10.2008 um 18:15:53 Uhr
Goto Top
Moin Chris-U,

kannst Du mal zum Spass die A.ID mit in die Select-Feldliste aufnehmen (zusätzlich zu "name" und "wert2") und prüfen, ob es Auswirkungen auf die Performance hat?

A.ID und B.ID sind doch auch die PKs der Tabellen A und B?

Grüße
Biber
Chris-U
Chris-U 28.10.2008 um 08:57:21 Uhr
Goto Top
Werd ich probieren, komme aber erst heute am späten nachmittag oder morgen dazu, da ich heute außer haus sein werde.
Würde mich auch über noch mehr vorschläge freuen.

Habe heute schon verucht das mit einem Subselect zu lösen, aber hatte noch ein Syntax-Problem^^
Chris-U
Chris-U 29.10.2008 um 11:38:32 Uhr
Goto Top
@Biber: hat leider nicht geholfen face-sad

Für den Augenblick habe ich eine Lösung gefunden, die für meine Bedürfnisse ausreicht, aber das Problem eigentlich nicht generell behebt.

In meinem Fall existiert zu jedem Datensatz aus Tabelle A genau ein Datensatz in Tabelle B.
Ich habe den LEFT JOIN zu einem einfachen JOIN gemacht und schon ist die Abfrage wieder flott.

Allerdings kann man bei der Problemstellung nicht immer davon ausgehen dass eine 1:1 Zuordnung möglich ist. Rein von der Logik her gesehen müsste auch ich in meinem Fall einen LEFT JOIN verwenden. Nur durch andere Umstände ergibt sich bei mir der Sonderfall, dass eine 1:1 Zuordnung möglich ist.

Ich kennzeichne das Thema noch nicht als gelöst, da noch keine Lösung gefunden wurde, den LEFT JOIN zu beschleunigen.

In meinem Sonderfall wird auch in beiden durchsuchten Feldern nach dem gleichen String gesucht, daher ist es auch denkbar mit:
WHERE concat(`A`.`name`, `B`.`Wert2`) LIKE "%test3%"
den string zu suchen. Auch concat arbeitet sehr schnell, aber kann andere Probleme mit sich bringen und funktioniert auch nur in meinem Sonderfall.

Es sind also noch weitere Lösungen gesucht.

Grüße,
Christopher
godlie
godlie 30.10.2008 um 16:12:12 Uhr
Goto Top
hallo wie wäre es denn mit Indizies über die Spalten A.Name und B.Wert ?
Da es sich ja nur um Strings handeln sollte,......

http://dev.mysql.com/doc/refman/5.1/de/mysql-indexes.html

Aber im allgemeinen, überleg dir ein Redesign der DB hab selber solch furchtbar betreuen müssen, dass geht auf Dauer schief.

grüße