Sql postgres中同时计算平均值和标准差的有效方法
stddev_pop()必须将AVG()计算为标准偏差完整计算的一部分(除非有我不知道的快捷方式) 对于上下文,目标是测试这两个geom列之间的平均值差异 为了避免重新计算AVG(),是否有任何方法可以访问它 下面是一个查询示例:Sql postgres中同时计算平均值和标准差的有效方法,sql,postgresql,Sql,Postgresql,stddev_pop()必须将AVG()计算为标准偏差完整计算的一部分(除非有我不知道的快捷方式) 对于上下文,目标是测试这两个geom列之间的平均值差异 为了避免重新计算AVG(),是否有任何方法可以访问它 下面是一个查询示例: select avg(st_length(cons.geom)) as source_avg_length, avg(st_length(csn.geom)) as target_avg_length, stddev_pop(st_lengt
select
avg(st_length(cons.geom)) as source_avg_length,
avg(st_length(csn.geom)) as target_avg_length,
stddev_pop(st_length(cons.geom)) as source_std_length,
stddev_pop(st_length(csn.geom)) as target_std_length
from
received.conflation_osm_no_service cons,
received.conflation_stress_network csn ;
还有EXPLAIN ANALYZE
的输出,这让我想到,如果我请求avg()和stddev_pop(),它将只执行avg()计算一次并重用它:
根据评论,我将执行时间缓慢归因于多个平均聚合,而实际上这是由于不必要的联接。要将两个表合并到一个结果中,必须在联接之前进行聚合:
select *
from
(
select
avg(st_length(geom)) as source_avg_length,
stddev_pop(st_length(geom)) as source_std_length
from received.conflation_osm_no_service cons
) as src
cross join
(
select
avg(st_length(geom)) as target_avg_length,
stddev_pop(st_length(geom)) as target_std_length,
from
received.conflation_stress_network csn ;
) as tgt
或为每个表获取一行:
select 'source' as tablename,
avg(st_length(geom)) as avg_length,
stddev_pop(st_length(geom)) as std_length
from
received.conflation_osm_no_service cons
union all
select 'target',
avg(st_length(geom)),
stddev_pop(st_length(geom)),
from
received.conflation_stress_network csn ;
stddev_pop()
不需要计算中间平均值。有许多方法可以实现相同的计算。您的查询正在进行11645x14380=167455100行的交叉连接。除了生成1.67亿行、存储在内存和/或磁盘上、扫描整个结果集并计算平均值之外,没有其他算法可以计算这些数字吗?生成这个交叉连接,然后扫描它是最昂贵的操作,平均两次只需要最小的开销。你说得对@krokodilko,我在一个单独的查询中计算了每个表的统计数据,几乎是即时的。这两个表在原始查询中连接的原因很明显吗?似乎是不必要的步骤。为什么要在两个表之间创建交叉连接?你不应该用一个JOIN
来代替吗?但只要没有WHERE子句,Seq Scan将是唯一明智的选择,因为您需要两个表中的所有行。我没有意识到查询将以这种方式执行,没有理由我不能简单地分别执行查询,然后合并结果。