From 0d56f22912b758b59d74b4c3c2d6bdcb48826d7b Mon Sep 17 00:00:00 2001 From: Tyler Longwell Date: Fri, 17 Apr 2026 19:02:35 -0400 Subject: [PATCH] schema: add partial index on channel_members.pubkey MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The channel_members table only has a PK index on (channel_id, pubkey). Every query that looks up channels-for-a-user (WHERE pubkey = $1) does a sequential scan because the PK has channel_id first. get_accessible_channel_ids() runs on every REQ (subscription) message — it is the first thing the relay does after auth. On staging this has accumulated 5.6M seq scans reading 7.2B rows total (~5 scans/sec steady). Add a partial index on (pubkey) WHERE removed_at IS NULL, which covers the exact predicate used by the hot-path queries in sprout-db/channel.rs: - get_accessible_channel_ids (line 529) - channel_ids_for_pubkey (line 531) - is_member (line 491) - get_member_role (line 604) The table is small today (1,360 rows) so each scan is <0.3ms, but this is O(N) per subscription and will degrade linearly as users grow. --- schema/schema.sql | 3 +++ 1 file changed, 3 insertions(+) diff --git a/schema/schema.sql b/schema/schema.sql index a7503839..9126fb37 100644 --- a/schema/schema.sql +++ b/schema/schema.sql @@ -66,6 +66,9 @@ CREATE TABLE channel_members ( PRIMARY KEY (channel_id, pubkey) ); +CREATE INDEX idx_channel_members_pubkey ON channel_members (pubkey) + WHERE removed_at IS NULL; + -- ── Users ───────────────────────────────────────────────────────────────────── CREATE TABLE users (