假设我有一个包含一千个用户和五千万个user_actions的表。少数用户有超过一百万个动作,但大多数都有数千个。
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 :(得分:1)
在(user_id, created_at)
这将允许PostgreSQL进行索引扫描以找到第一条记录。
这是多列索引产生重大影响的情况之一。
注意我们首先放置user_id,因为它允许我们有效地选择我们感兴趣的索引的子部分,然后从那里只是快速遍历以获得最新的created_at日期,但不是很多该区域有死行。