提高postgresql中自联接的效率

时间:2018-06-17 18:27:53

标签: sql amazon-redshift

我正在使用自联接执行以下查询:

with t as (
      SELECT *, TIMESTAMP 'epoch' + tstamp * INTERVAL '1 second' as tstamp2
      FROM
      mytable 
      WHERE id = 'a'
      LIMIT 1000
    )
select v1.id as id, date_trunc('hour', v1.tstamp2) as hour, v1.value as start, v2.value as stop 
from 
    t v1 join 
    t v2 
        on v1.id = v2.id and
        date_trunc('hour', v1.tstamp2) = date_trunc('hour', v2.tstamp2) and
        v1.tstamp2 < v2.tstamp2 
where 1=1
limit 100;

表格如下:

id   tstamp    value    tstamp2

我的目标是在同一小时内为一个id输出“value”的所有组合。 我有100.000个独特的ID和数百万行。 这非常缓慢且效率低下。 有没有办法打破查询,以便自联接操作时间分区(例如每小时),以提高此类查询的速度?

我有100.000个唯一ID和数百万行。

编辑:我发现这似乎是我想要做的但不知道如何实现:

  

如果你知道的不仅仅是你对...的属性有所了解   间隔,你可能能够改善一些事情。例如,如果   间隔落入非重叠桶,然后你可以添加一个   限制双方的水桶是平等的。 Postgres是一个   使用等式连接约束比使用范围更好   约束,所以它能够匹配行,只做匹配   O(N ^ 2)在每个桶中工作。

1 个答案:

答案 0 :(得分:1)

这回答了最初标记的问题 - &#34; Postgres&#34;,而不是&#34; Redshift&#34;。

不幸的是,Postgres实现了CTE,然后排除了索引的使用。您在CTE中没有ORDER BY,因此正在选择任意行。

一个解决方案是临时表和索引:

CREATE TEMPORARY TABLE t as
      SELECT t.*,
             TIMESTAMP 'epoch' + tstamp * INTERVAL '1 second' as tstamp2,
             DATE_TRUNC('hour', 'epoch' + tstamp * INTERVAL '1 second') as tstamp2_hour
      FROM mytable t
      WHERE t.id = 'a'
      LIMIT 1000;

CREATE INDEX t_id_hour_tstamp2 ON t(id, tstamp2_hour, tstamp2);

select v1.id as id, v1.tstamp2_hour as hour, v1.value as start, v2.value as stop 
from t v1 join 
     t v2 
        on v1.id = v2.id and
           v1.tstamp2_hour = v2.tstamp2_hour and
           v1.tstamp2 < v2.tstamp2 
limit 100;