mirror of
https://github.com/basecamp/once-campfire.git
synced 2026-10-08 15:50:08 +09:00
Find the messages a refresh replaces through an index
Every room visit and every reconnection asks for the messages updated since the page was rendered. That query filtered the room by updated_at and sorted it by created_at, so SQLite walked every message in the room: about 220-360 ms in a room of a million messages. An index on (room_id, updated_at) finds the few updated messages directly. Sorting on +created_at keeps SQLite on that index once messages are also indexed by (room_id, created_at): with both, the planner otherwise walks the room in creation order looking for updated rows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JVFo3Lt9T8M5NR7KxVvsZ2
This commit is contained in:
@@ -36,7 +36,10 @@ module Message::Pagination
|
||||
scope :page_after, ->(message) { after(message).first_page }
|
||||
|
||||
scope :page_created_since, ->(time) { where("created_at > ?", time).first_page }
|
||||
scope :page_updated_since, ->(time) { where("updated_at > ?", time).last_page }
|
||||
# Sorting on +created_at, which no index covers, has SQLite find the few messages updated since
|
||||
# through (room_id, updated_at) and sort just those, instead of walking the whole room by
|
||||
# (room_id, created_at) looking for them.
|
||||
scope :page_updated_since, ->(time) { Page.load(where("updated_at > ?", time).reorder(Arel.sql("+messages.created_at")), :last, PAGE_SIZE) }
|
||||
end
|
||||
|
||||
class_methods do
|
||||
|
||||
Reference in New Issue
Block a user