Hallo,
ich hatte mir mit ‘explain’ den Query Plan einer langsamen Abfrage angezeigt und dabei festgestellt, dass ein sequential Scan benutzt wurde, weil ich vergessen hatte einen Index zu erzeugen. Dann habe ich den Index erstellt und sogar nochmals ein ‘analyse’ gestartet.
Leider war danach die Abfrage immer noch genauso langsam und Explain zeigte immer noch den gleichen sequential Scan. Auch ein Ab- und Anmelden des Clients brachte nichts. Vor ein paar Tagen hatte ich einen ähnlichen Fall der genauso ablief: Erst gab es keine Verbesserung und erst nach Stunden - oder als ich den Server neu gestartet hatte (ich weiß das nicht mehr so genau) - wurde der Index im Plan berücksichtigt und die Abfrage ging flott.
Deshalb meine Frage:
Was muss man tun, damit eine Änderung des Umfeldes (Index erstellen, Analyse durchführen etc.) berücksichtigt wird und veraltete Strategien verworfen werden?
Ausser bei prepared Queries wird für jede Anfrage ein neuer Plan erstellt, du musst also nichts ändern, damit das berücksichtigt wird. Allerdings ist der Planer auf die Hilfe von z.B. VACUUM und ANALYZE angewiesen, um korrekte Statistiken zum Arbeiten zu haben.
In deinem Fall muss das aber nicht heissen, das ein Index jetzt auch wirklich genutzt wird, nur weil dies in einem ähnlich gelagerten Fall geholfen hat.
Depends. Indexe können helfen, müssen aber nicht. Zum Bleistift nicht dann, wenn der Index nicht zur Abfrage paßt. Aber um das zu beurteilen, müßte man sehen, was explain analyse dazu meint.
D.h. es wird ein sequential Scan benutzt, obwohl es einen Index über das Feld antragnr_fk gibt. Aber der konnte nicht für
....
where a4.antragnr_fk = a.antragnr_pk
benutzt werden, weil a.antragnr_pk vom Typ decimal(8) und a4.antragnr_fk vom Typ int4 war. Es wird bei Vergleichen von verschiedenen Typen wohl immer auf den mächtigsten Typ erweitert.
Die unterschiedlichen Type basieren übrigens darauf, dass die eine Tabelle (a) aus einer steinalten ORACLE-Datenbank übernommen wurde.
Ich muss da wohl mal Einiges anpassen.
Vorerst habe ich die Abfrage mit einem
....
where a4.antragnr_fk = a.antragnr_pk::int4
angepasst, so dass der Index jetzt benutzt werden kann - und auch wird .
PostgreSQL 8.2.5 on i686-pc-linux-gnu, compiled by GCC gcc (GCC) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
vor einem Vierteljahr eigenhändig aus den damals aktuellen Sourcen übersetzt.
Das Verhalten läßt sich übrigens prima reproduzieren:
nehme ich den Zusatz ‘::int4’ raus, macht er einen Sequential Scan; mit dem Zusatz, wird der Index benutzt und die Abfrage ist mehr als 100 Mal so schnell.