2017-02-15 34 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

也許,但你可以掃描索引轉發或向後如此不確定在這種情況下,如果這個查詢會關心這麼多 –