[英]Improving efficiency of a self join in postgresql
我正在通过自我联接执行以下查询:
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输出“值”的所有组合。 我有100.000个唯一ID和数百万行。 这是极其缓慢且效率低下的。 是否有一种方法可以中断查询,以便自连接可以按时间分区(例如每小时一小时)进行操作,以提高查询速度?
我有100.000个唯一ID和数百万行。
编辑:我发现这似乎是我想要做的,但不知道如何实现这一点:
如果您对间隔的属性了解不止,您可能可以进行改进。 例如,如果间隔属于非重叠存储桶,则可以添加一个约束,即两侧的存储桶相等。 具有相等联接约束的Postgres比具有范围约束的Postgres要好得多,因此Postgres能够匹配行并且仅在每个存储桶中执行O(N ^ 2)。
这将回答最初标记为“ Postgres”而不是“ Redshift”的问题。
不幸的是,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;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.