2017-02-15 66 views
0

假设我有一个包含一千个用户和五千万个user_actions的表。少数用户有超过一百万次的行动,但大多数有数千次。Postgres索引最近的外键

CREATE TABLE users (id, name) 
CREATE TABLE user_actions (id, user_id, created_at) 
CREATE INDEX index_user_actions_on_user_id ON user_actions(user_id) 

查询user_actions通过user_id是快速的,使用索引。

SELECT * 
FROM user_actions 
WHERE user_id = ? 
LIMIT 1 

但我想知道用户对最后行动。

SELECT * 
FROM user_actions 
WHERE user_id = ? 
ORDER BY created_at DESC 
LIMIT 1 

此查询抛出索引并执行表扫描,向后搜索,直到找到操作为止。对于最近处于活动状态的用户来说不是问题,对于没有用户的用户来说太慢了。

有没有办法调整这个索引,让postgres跟踪每个用户的最后一个动作? (对于奖励积分最后的N个动作!)

或者,建议备用策略?我想一个窗口函数的物化视图将会做到这一点。

+0

https://stackoverflow.com/questions/tagged/greatest-n-per-group+postgresql –

回答

1

创建于(user_id, created_at)

该指数将允许PostgreSQL的做一个索引扫描,找到第一个记录。

这是多列索引造成重大差异的情况之一。

注意,我们首先放置了user_id,因为它允许我们有效地选择我们感兴趣的索引的子部分,然后从那里获取最近的created_at日期,只是快速遍历,并不是很多在该地区的死行。

+0

可能想通过desc命令,也取决于如何写入SQL –

+0

也许,但你可以扫描索引转发或向后如此不确定在这种情况下,如果这个查询会关心这么多 –