MySQL: SELECT ist sehr langsam
-
Hi,
ich nutze hier aus einer Anwendung heraus eine MySQL-DB, welche im wesentlichen ein paar müde SELECTs beantworten soll. Mein Problem: das geht viel zu langsam, obwohl ich nicht mal 200000 Datensätze in der DB habe.
Die Datenbanstruktur selber besteht aus einem int(11), welcher als Indexwert und als Key verwendet wird, dann kommt ein kurzer Text bestehend aus einer Buchstaben/Zahlenkombination immer gleicher länge sowie noch ein paar Feldern mit ein paar Zahlenwerten. Das SELECT wird immer auf den Text ausgeführt und es werden immer die diesem Datensatz ebenfalls noch zugehörigen Zahlenwerte zurückgeliefert:
SELECT zahl1,zahl2,zahl3 FROM tabelle WHERE textval="113344FFRRTT"
So weit also nix wirkklich kompliziertes, dennoch habe ich folgendes beobachtet: bevor ich neue Daten importiere, sehe ich mit exakt diesem Statement nach, ob dieser wert für textval eventuell schon existiert. Und für genau den Fall, dass textval noch nicht existiert, benötigt SELECT ziemlich lange (bei 2500 abfragen kann ich schon locker mal 5 Minuten warten).
Was läuft hier schief, was könnte die Ursache dafür sein?
-
ich würd textval in ne eigene Tabelle auslagern. So sparst du dir den String-Vergleich.
Welcher Datentyp ist textval? VARCHAR oder nur CHAR?
-
Hi,
bisher war textval ein TEXT, daraus habe ich jetzt mal ein CHAR(14) gemacht und es noch auf UNIQUE gesetzt - das hat einen enormen Geschwindigkeitsschub gegeben.
Hm, was bringt mit textval in einer eigenen Tabelle? Da SELECT immer auf textval gemacht wird, wird der Stringvergleich doch in jedem Fall ausgeführt?
Wo lässt sich sonst noch was drehen?
-
Wenn ich mich richtig erinnere, dann sollte nicht irgendein Index gesetzt werden, sondern der, der in der Abfrage verlangt wird.
Ich kann mich aber gerade nicht erinnern, ob es die Felder im SELECT oder die Felder in der WHERE-Klausel waren...
Also ich würde den Index entweder auf zahl1, zahl2 und zahl3 setzen oder auf textval.
-
Hallo,
das klingt nach einem typischen Fall für ON DUPLICATE KEY.
Wenn du einen Index auf "textval" gesetzt hast, kannst du folgenden INSERT ganz beruhigt machen:INSERT INTO tabelle (`zahl1`, `zahl2`, `zahl3`, `textval`) VALUES ('11','22','33', '113344FFRRTT') ON DUPLICATE KEY UPDATE timestamp=NOW();
Dies setzt natürlich voraus dass du irgendein UPDATE-fähiges Feld hast. Timestamp macht sich da immer ganz gut. Hat dann auch den Vorteil dass du zeitlich nachvollziehen kannst, wann was geändert oder hinzugefügt wurde.
Wichtig ist hierbei eben nur der Index! Aber den hast du ja eh schon!
LG