greenplum/postgreSQL中的count(*)和count(*over()性能差异



我想查询明细数据和明细数据的总数。一般来说,这需要两句SQL语句。例如,一个是select col1, col2, col3 from tb limit 50 offset 0,另一个是select count() from tb。为了减少查询的数量;从tb中选择col1、col2、col3、count((而不是((totol_count;相反

但我发现后者(select col1, col2, col3, count(*) over () totol_count from tb limit 50 offset 0(有时比前者慢得多。为什么?这两种方法的性能有何不同?

这是解释分析。我只是把不同的放在上面。

  1. 从tb限制20偏移0中选择col1限制(成本=743828.93.747114.71行=200宽=287((实际时间=2290.254.2390.969行=200圈=1(->聚集运动20:1(切片3;分段:20((成本=743828.93.747114.71行=200宽度=287((实际时间=2290.248.2390.933行=200循环=1(->限制(成本=743828.93.747110.71行=10宽=287((实际时间=2285.350.2385.507行=200个环路=1(

  2. 从tb中选择计数(*(合计(成本=6123212.33.6123212.34行=1宽=8((实际时间=2339.615..2339.616行=1个循环=1(->聚集运动20:1(切片2;分段:20((成本=6123212.10.6123212.32行=1宽度=8((实际时间=635.672.2339.433行=20循环=1(->合计(成本=6123212.10.6123212.11行=1宽=8((实际时间=633.879.633.879行=1个循环=1(

  3. 从tb限制20偏移量0中选择col,count(*(over((限制(成本=743828.93.747113.21行=200宽度=287((实际时间=57787.942.57788.339行=200循环=1(->WindowAgg(成本=743828.93.307341631.82行=18670608宽度=287((实际时间=57787.936.57788.310行=200个循环=1(->采集运动20:1(切片3;分段:20((成本=743828.93.307014896.18行=18670608宽度=287((实际时间=1514.368..32796.802行=18735134循环=1(

只有在看到您的执行计划后,才能确定哪一个更适合您。

但如果你运行Analyze足够多,你可以使用:

SELECT reltuples::bigint AS estimate
FROM   pg_class
WHERE  oid = 'tb'::regclass;

它非常快,但不会给你准确的计数,而是近似的计数。准确性将取决于运行Analyze的频率。

select count(*) from tb慢的原因与MVCC有关在PostgreSQL中实现。多个事务可以看到不同的数据状态意味着不可能对于";COUNT(*(";对整体数据进行汇总桌子从某种意义上说,PostgreSQL必须遍历所有行。这通常会导致顺序扫描读取关于行。PostgreSQL 中的慢速计数

最新更新