Я сгенерировал некоторые данные для тестирования следующим образом:
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);
Ваш запрос успешно выполняется на этом, но не совсем генерирует тот же план, я получаю вложенный цикл в нижней части руки, а неСлияние и последующее сканирование в init-плане - вы не выключили enable_seqscan Надеюсь?
Решение, использующее только одно сканирование таблицы:
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
Плохая новость заключается в том, что на моем компьютере это на самом деле работает хуже , особенно если я достаточно увеличу work_mem, чтобы избежать первой сортировки диска (создание player_stats, сортировка по flg).Несмотря на то, что увеличение work_mem сократило время запроса вдвое, так что я думаю, что это хотя бы начало?
Сказав это, мои запросы выполняются в течение примерно 5 секунд, чтобы обработать входные строки 10E6 во временном_сим_макс.Величина быстрее, чем вы разместили.Ваша таблица вписывается в ваш буферный кеш?Если нет, то решение для одного сканирования может быть гораздо лучше для вас.(Какую версию Postgresql вы используете? "Объяснять (анализировать, буферизовать) выбирать ..." покажет вам количество попаданий / промахов в буфере в 9.0 или просто посмотреть на настройку "shared_buffers" и сравнить с размером таблицы)