MySQL [5.0.67] Index verwirrt mich
StefanRHRO
- datenbank
0 Ilja0 StefanRHRO0 StefanRHRO
Hallo,
folgende Query:
SELECT c.tabelle_id, c.tabelle_clients_tel, c.tabelle_clients_handy, c.tabelle_prio
FROM cap_tabelle c
WHERE c.tabelle_campaign_status <=0
AND c.tabelle_status <=6
AND c.tabelle_inuse <=0
AND c.tabelle_prio <=6
AND c.tabelle_touch <=60
AND c.tabelle_wvdate <= now( )
ORDER BY c.tabelle_prio ASC , tabelle_touch ASC , tabelle_wvdate ASC
wird mittels eines Multiindexes in einem kleinen PHP Skript abgefackelt. Der MultiIndex (nennt man das überhaupt so?) ist wie im WHERE Bereich zu sehen aufgebaut, keine Varchars, Texte, Blobs oder ähnliches verstecken sich dahinter, sondern nur INT und ein DATETIME Feld [tabelle_wvdate]. Diese Abfrage braucht bei 653334 rund 5.5 sek. um ein Resultat zu geben. EXPLAIN sagt mir, dass er where für den WHERE Bereich benutzt, für das Sortieren aber filesort. Was mich daran wundert ist eine Aussage im Manual (7.2.12 ORDER BY-Optimierung) ich zitiere: "Der Index kann auch verwendet werden, wenn die ORDER BY-Klausel dem Index nicht exakt entspricht, solange alle nicht verwendeten Bestandteile des Indexes und alle zusätlichen ORDER BY-Spalten Konstanten in der WHERE Klausel sind. [...]" <-- Ist aber bei mir gegeben. Hat jemand evtl. ne Idee, wie ich das fixen könnte?
Grüße Stefan Riedel
yo,
tuning ist wohl mit das schwierigste, weil man sich schon gut mit dem jeweiligen dbms auskennen muss. du befindest dich also in der königsdiziplin und dort gilt der grundsatz, immer probieren über studieren.
zum einen würde es auch interessant sein zu wissen, wie genau du den index erstellt hast. zum anderen wie viele datensätze du als resultset zurück bekommst und wie die kardinalität der daten aussieht, sprich sind viele werte in einer spalte gleich oder unterscheiden sie sich stark. zum anderen ist deine abfrage auch insofern kritisch, da du nicht auf exakte werte mit = prüfst, sondern wertebereiche. es gibt also im vorfeld viel zu klären, bevor man vermuten kann, was deine abfrage schneller machen würde. in der praxis ptüfen muss man das dann eh immer.
Ilja
yo,
Hy Ilja,
tuning ist wohl mit das schwierigste, weil man sich schon gut mit dem jeweiligen dbms auskennen muss. du befindest dich also in der königsdiziplin und dort gilt der grundsatz, immer probieren über studieren.
Diesen Grundsatz kenne ich, nur oft verheddert man sich denn auch, und am Ende ist es schlimmer als vorher. ;)
zum einen würde es auch interessant sein zu wissen, wie genau du den index erstellt hast. zum anderen wie viele datensätze du als resultset zurück bekommst und wie die kardinalität der daten aussieht, sprich sind viele werte in einer spalte gleich oder unterscheiden sie sich stark. zum anderen ist deine abfrage auch insofern kritisch, da du nicht auf exakte werte mit = prüfst, sondern wertebereiche. es gibt also im vorfeld viel zu klären, bevor man vermuten kann, was deine abfrage schneller machen würde. in der praxis ptüfen muss man das dann eh immer.
Wie gesagt anfangs war es nen Multi Index allen Feldern, die in der Where Bedingung stehen, dort ist mir mitlerweile aber im Explain aufgefallen, dass in rows, die Summe aller Datensätze stand, so habe ich es auf tabelle_campaign_status verringert. Die einzigen Felder, die noch ne höhere Kardinalität als 3 erreichen können, sind tabelle_prio (1-6) und tabelle_status (0-10) und tabelle_touch (0-60). UNd mit tabelle_prio scheint er arge Probleme zu haben, sobald ich dieses Feld in den Index mit einbaue, fliegen mir die Ausführungszeiten um die Ohren... :(
Zu den Werte Bereichen, da könnte ich sicher an der Stelle: tabelle_prio und tabelle_status drehen, nur denn weiß ich nicht, ob die Abfragen wieder zuviel werden, da das Skript, welches die Query nutzt, schon häufig auf die DB zu greift. Weil wenn ich erst nach dem Status 1, denn 2 und so schaue, kann es schon passieren, dass das zu viel wird.
Falls noch Infos gewünscht, kann ich die gerne liefern. :)
Ilja
Aloa,
danke für deine Hilfe. Werds jetzt wohl über Temporäre Tabelle lösen.
Gruß Stefan