PostgreSQL基于范围的连接工作太慢

时间:2015-08-11 11:58:10

标签: sql performance postgresql join

支持我有2个表,其中包含一些具有以下结构的事件和回调:

Event:
id
timestamp (BIGINT, btree index)
type (VARCHAR, btree index)
(pair index (timestamp, type))

Callback:
id
timestamp (BIGINT, btree index)
event_type

事件表包含约(M =)300000行,回调约为(N =)25000。 我试着做一些想法:

SELECT * FROM Callback
JOIN Event
ON ABS(Callback.timestamp - Event.Timestamp) < 300000 AND
    Callback.event_type = Event.type;

按照计划,它应该适用于O(N log(M)+ R)(其中R - 是结果大小.R大约是1000000(每个订单的AVG 50事件)),但实际上它可以工作大约40强大的CPU上的分钟。

UPD:抱歉,忘了说,我试试:

SELECT * FROM Callback
JOIN Event
ON Event.Timestamp < Callback.timestamp + 300000 AND
   Event.Timestamp > Callback.timestamp - 300000 AND
   Callback.event_type = Event.type;

但没有任何改变。

谁能告诉我,我做错了什么? 谢谢。

2 个答案:

答案 0 :(得分:0)

以下内容可能适用于event(type, timestamp)的索引:

SELECT *
FROM Callback c JOIN
     Event e
     ON c.event_type = e.type AND e.Timestamp > c.timestamp - 300000;

这个想法是留下一个没有修改的时间戳列。这些可以阻止使用索引。

我想知道你是否也希望c.timestamp >= e.TimeStamp有条件。您的性能问题可能只是您要返回的数据量。

答案 1 :(得分:0)

重新排列连接,以便将一列表示为另一列的函数,如下所示:

SELECT * FROM Callback
JOIN Event
ON (Event.Timestamp > (Callback.timestamp - 300000) AND
    Callback.event_type = Event.type);

......或......

SELECT * FROM Callback
JOIN Event
ON (Callback.timestamp > (Event.Timestamp + 300000) AND
    Callback.event_type = Event.type);

(我认为我得到了&gt;&#39; s&lt;&#39s正确的方式。)

这允许使用列上的索引,但我不排除在两个表上都需要完整扫描的可能性。这取决于值的数据分布。