查询优化

时间:2011-01-07 17:35:49

标签: sql optimization postgresql query-optimization

这是我当前的查询,它有效,但速度很慢:

    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;

我在固定(或几乎固定)的100个范围内进行分组,这些范围由按id_player分组的avg(flg_vpip)排序。

在这里,我粘贴了结果,以防有助于理解: https://spreadsheets0.google.com/ccc?key=tFVsxkWVn4fMWYBxxGYokwQ&authkey=CNDvuOcG&authkey=CNDvuOcG#gid=0

我想知道在这种情况下是否有比ROW_NUMBER()更好的功能,我觉得我做了太多的子选择,但我不知道如何优化它。

我非常感谢任何帮助。

如果不清楚,请告诉我。

谢谢。

编辑:

我创建auxtable 2的原因是因为当我使用(ROW_NUMBER()OVER(ORDER BY flg),并使用其他agregate命令,如avg(amt_won)和count(*),这是必不可少的,我得到一个错误说flg应该在聚合函数中,但是我不能用flg的聚合函数来命令。

1 个答案:

答案 0 :(得分:2)

我生成了一些数据来测试,如下所示:

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-plan中的合并和seq扫描 - 你还没有关闭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秒钟来处理temporary_six_max中的10E6输入行,这比你发布的要快一个数量级。您的表是否适合您的缓冲区缓存?如果没有,单扫描解决方案对您来说可能更好。 (您使用的是哪个版本的Postgresql?“解释(分析,缓冲)选择...”将显示9.0中的缓冲区命中/未命中率,或者只查看“shared_buffers”设置并与表格大小进行比较)