2011-01-07 16 views
0

Das ist meine aktuelle Abfrage ist, es funktioniert, aber es ist langsam:Abfrageoptimierung

SELECT row, MIN(flg) ||' to ' ||Max (flg) as xyz , avg(amt_won), count(*) 
FROM(
SELECT (ROW_NUMBER() OVER (ORDER BY flg))*100/ 
(SELECT count(*)+100 as temprow FROM temporary_six_max) as row, flg, amt_won 
FROM temporary_six_max 
    JOIN (
    SELECT id_player AS pid, avg(flg_vpip::int) AS flg 
    FROM temporary_six_max 
    GROUP BY id_player 
    ) AS auxtable 
    ON pid = id_player 
) as auxtable2 
group by 1 
order by 1; 

Ich Gruppierung in festen (oder fast festen) 100 Bereiche zählen, die von avg (flg_vpip) geordnet nach id_player gruppiert.

Hier habe ich die Ergebnisse für den Fall, klebte es verstehen helfen zu können: https://spreadsheets0.google.com/ccc?key=tFVsxkWVn4fMWYBxxGYokwQ&authkey=CNDvuOcG&authkey=CNDvuOcG#gid=0

Ich frage mich, ob es eine bessere Funktion als ROW_NUMBER() in diesem Fall zu verwenden ist, und ich fühle mich wie ich auch tue, viele Subselects, aber ich weiß nicht, wie man es optimiert.

Ich werde sehr jede Hilfe zu schätzen wissen.

Wenn etwas nicht klar ist, lass es mich wissen.

Vielen Dank.

EDIT:

Der Grund I auxtable 2 erstellt wurde, ist, weil wenn ich (ROW_NUMBER() OVER (ORDER BY FLG) und andere Agregate Befehle verwenden, wie avg (amt_won) und COUNT (*), die wesentlich ist, erhalte ich eine Fehlermeldung, dass flg in der Aggregatfunktion sein sollte, aber ich kann nicht von einer Aggregatfunktion von flg bestellen

+1

Bitte senden Sie auch die Ausgabe von EXPLAIN ANALYSE. Und erklären Sie bitte, was Sie eigentlich mit den geschachtelten Auswahlen erreichen wollen (ich meine * auxtable4 * nicht die abgeleitete Tabelle * autxtable2 * Derzeit verstehe ich das Ziel dieser –

+0

Ich postete die EXPLAIN ANALYSE in den gdocs auf dem obigen Link Die Antwort für die Erstellung von autxtable4 und autxtable 2 sind auf dem editierten Post. Danke. – joaoavf

+1

'max (row_number())' ist im Wesentlichen 'count (*) über (...)'. Aber ich verstehe immer noch nicht die Berechnungen, die du dazu tust (Dividieren und die +100) Aber ich verstehe jetzt die Absicht –

Antwort

2

ich einige Daten erzeugt, wie dies zu testen mit:.

create table temporary_six_max as 
select id_player, flg_vpip, 
     random()*100 * (case flg_vpip when 0 then 1 else -1 end) as amt_won 
from (select (random()*1000)::int as id_player, random()::int as flg_vpip 
     from generate_series(1,1000000)) source; 
create index on temporary_six_max(id_player); 

Ihre Abfrage wird erfolgreich dagegen ausgeführt, generiert jedoch nicht die gleiche Abfrage Plan, ich bekomme eine verschachtelte Schleife im Unterarm statt eine Zusammenführung und eine Seq-Scan im Init-Plan - Sie haben enable_seqscan nicht deaktiviert, hoffe ich?

Eine Lösung nur einen einzigen Scan der Tabelle mit:

select row, min(flg) || ' to ' || max(flg) as xyz, avg(amt_won), count(*) 
from (select flg, amt_won, ntile(100) over(order by flg) as row 
     from (select id_player as pid, amt_won, 
        avg(flg_vpip::int) over (partition by id_player) as flg 
      from temporary_six_max 
      ) player_stats 
    ) chunks 
group by 1 
order by 1 

Die schlechte Nachricht ist, dass dies tatsächlich durchführt schlimmer auf meiner Maschine, vor allem, wenn ich work_mem genug stoßen die erste Scheibe Art zu vermeiden (macht player_stats, sortiert nach flg). Obwohl das Erhöhen von work_mem die Abfragezeit halbiert hat, ist das zumindest ein Anfang?

Nach diesen, meine Abfragen laufen für ca. 5 Sekunden, um 10E6 Eingabe Zeilen in temporary_six_max zu verarbeiten, die eine Größenordnung schneller ist als Sie gebucht. Passt Ihre Tabelle in Ihren Puffer-Cache? Wenn nicht, ist eine Single-Scan-Lösung möglicherweise viel besser für Sie. (Welche Version von Postgresql verwendest du? "Explain (analyze on, buffers on) select ..." zeigt dir die Pufferhit/Miss-Rate in 9.0, oder schau dir einfach deine "shared_buffers" -Einstellung an und vergleiche sie mit der Tabellengröße)