2017-08-16 69 views
1

我有入我存储的“会话”记录的PostgreSQL表。这些会话有时会很快创建(有时会达到几百秒)。我显然不能让桌子无限增长。所以我有一个守护进程,它周期性地扫描表格,强加一个外部可配置的大小限制。清洁最古老的最大行数

当记录数超过限制时,我想抽出最早的记录(使用限制值),将它们以文本形式写入单独的(非关系)日志文件,然后从表中删除它们。我现在正在做的工作,但有一个很高的限制,它是非常缓慢的。我当前的查询是这样的:

SELECT * FROM sessions ORDER BY modified DESC OFFSET 1000000 LIMIT 10000; 

我的程序然后记录那些最近最少修改的记录到离线的历史,然后做一个单独的SQL DELETE砸行。问题是,如果我说1000010记录需要25-30秒的顺序才能获得这10条记录,那么执行上面的查询。在modified字段上创建索引似乎没有任何明显的影响,所以我假设postgres在它计算出前100万条记录之前创建了一个临时数据集,然后排除它们。

是否有更好的方法来做到这一点,以获得相同的结果?我基本上只想获得表中最早的“count(*) - N”行。

(现在我知道我可以先做一个独立的查询来获取表的count(*),然后反向查询的ORDER BY条款,然后只用LIMIT但这似乎缺憾。这将是我的备用,但我更喜欢做什么我上面直接如果可能的话说明。)

+1

1)你能在你的查询运行'EXPLAIN'以确定是否PostgreSQL的实际打你创建的索引? 2)您是否愿意选择“修改”在给定时间戳之前的所有记录?这__可以更好地找到索引。 –

+0

因此,事实证明,我过分简化了我的例子。这个问题比我想象的要多(我忽略了上面的WHERE子句,尽管我没有认为它是相关的,但事实证明这是至关重要的)。感谢@AndrewRueckert提供运行EXPLAIN的建议。我从中学到了很多东西(它需要连续扫描等等),并且基本上按照您的建议进行:首先使用SELECT来确定参考时间戳,然后使用反向SELECT来查找比时间戳更早的行。新流量加上索引后,典型情况下降至几秒钟。 –

回答

0

我觉得这里的问题是偏移,因为你的偏移1000000做了很多的扫描,这使得不使用索引。我不知道你的桌子有多少,但为什么你不使用修改日期来分割你的桌子。在这种情况下,您将确切知道您需要访问和删除数据表的哪个分区。

+0

我认为问题在于缺少密钥。 – wildplasser

相关问题