我有入我存储的“会话”记录的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)你能在你的查询运行'EXPLAIN'以确定是否PostgreSQL的实际打你创建的索引? 2)您是否愿意选择“修改”在给定时间戳之前的所有记录?这__可以更好地找到索引。 –
因此,事实证明,我过分简化了我的例子。这个问题比我想象的要多(我忽略了上面的WHERE子句,尽管我没有认为它是相关的,但事实证明这是至关重要的)。感谢@AndrewRueckert提供运行EXPLAIN的建议。我从中学到了很多东西(它需要连续扫描等等),并且基本上按照您的建议进行:首先使用SELECT来确定参考时间戳,然后使用反向SELECT来查找比时间戳更早的行。新流量加上索引后,典型情况下降至几秒钟。 –