Rolf B: Optimierung MySQL-Query

Beitrag lesen

Hallo bobby,

welche MYSQL-Funktion verwendest Du?

Die Frage versteh ich nicht. Ich geh jetzt davon aus, dass du die Version wissen wolltest: 5.6

Äh ja... 😳 - viele Grüße, Siegmund Freud. Ich wollte die Version wissen, um im Fall der Version 8 die RANK-Funktion vorschlagen zu können. In 5.6 gibt's die noch nicht.

kannst Du MYSQL Routinen (Stored Procedures) verwenden? Sowohl das Knowhow als auch von die DB-Rechte betreffend?

Könnte ich. Inwieweit würde dies den query beschleunigen?

Meine Idee wäre, diese komplexe Query aufzuteilen und das Herumrechnen mit Variablen in der Query zu entfernen. Aus meiner Sicht ist das Updaten von Variablen in einer Query fragwürdig, weil Du Dich damit an einen bestimmten Execution Plan bindest. Ändert der sich, ändert sich ggf. auch die Art wie die Variablen aktualisiert werden. Ohne Routinen bedeutet das mehrere Server-Roundtrips, mit Routinen bleibt es im Server.

muss es unbedingt die Query sein oder hast Du ein nachgelagertes Stück Programm, dass die Daten weiterverarbeitet?

Ja, es muss ein query sein. Möchte gern die Daten qualifiziert haben. Im Moment hab ich eine recht komplexe PHP - Anwendung auf eine Antwortzeit um die 200ms beschleunigt. Von daher möchte ich da nicht allzuviel Code dazu packen. Mein oben genannter query wird übrigens in 0,04s ausgeführt.

40ms für dieses Monster ist schnell - dann hast Du entweder eine kleine Table oder die DB hat wenige Nutzer und kann alles cachen. Wenn Du viele Daten hast, musst Du diese Query definitiv unter Last beobachten. Wenn Du auf dem Preis keinen Sekundärindex hast, solltest Du überlegen, ob man einen anlegt - dann aber den möglichen Einfluss auf Insert/Update/Delete-Statements beachten.

Ich hatte gestern auf meiner lokalen MySQL 5.6 Installation etwas zum Thema rumgespielt - ohne wirklichen Erfolg - und dabei hat sich mir die Frage gestellt, was Du bei Sätzen machst die den gleichen Preis haben. Deine existierende Vorgänger/Nachfolger Logik würde da undefiniert arbeiten; je nach dem, ob die gesuchte ID in einer Gruppe gleicher Preise die erste, letzte oder eine mittlere ist, würden Vorgänger und Nachfolger einen gleichen oder anderen Preis haben. Ob das für Dich ein Problem darstellt, hängt natürlich von deinen Daten ab, das kannst Du nur selbst wissen.

Wenn man die Aufgabe auf mehrere Queries verteilt, würde ich das so machen:

select @preis := preis from entries where id=@id;
select @low_id  := id, preis from entries where preis < @preis order by preis desc limit 1;
select @high_id := id, preis from entries where preis > @preis order by preis      limit 1;

select * from entries where id in (@low_id, @id, @high_id);

Die Queries 2 und 3 könnte man auch als Subselect in Query 4 integrieren. Query 1 nicht (oder du müsstest sie doppeln). Das bringt - meiner Meinung nach - aber nur dann wirklich Nutzen, wenn man damit Server-Anfragen spart; deswegen die Frage nach der Routine.

Kannst ja mal gucken ob deine Abfrage auf diesem Weg schneller wird. Auf jeden Fall ist sie lesbarer!

Rolf

--
sumpsi - posui - clusi