mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-11-04 10:47:32 +00:00
core: index group members by role for moderator lookup
The moderator lookup of a large group read every member row of the group to filter on role, holding the database connection while it ran: 178 ms on average and 4.8 s at most on one device. A new index on (user_id, member_role, group_id) serves the role-filtered member queries. The (user_id, group_id) index stays, so the other queries keep their plans and the order of their results.
This commit is contained in:
1 parent
5a5a927821
commit
1b8af22623
8 files changed
+58
-6
No files matched your search
@@ -172,6 +172,7 @@ library
|
||||
Simplex.Chat.Store.Postgres.Migrations.M20261010_invite_member_via_group
|
||||
Simplex.Chat.Store.Postgres.Migrations.M20261012_delivery_job_notification
|
||||
Simplex.Chat.Store.Postgres.Migrations.M20261016_badge_store_receipts
|
||||
Simplex.Chat.Store.Postgres.Migrations.M20261018_member_role_index
|
||||
else
|
||||
exposed-modules:
|
||||
Simplex.Chat.Archive
|
||||
@@ -353,6 +354,7 @@ library
|
||||
Simplex.Chat.Store.SQLite.Migrations.M20261010_invite_member_via_group
|
||||
Simplex.Chat.Store.SQLite.Migrations.M20261012_delivery_job_notification
|
||||
Simplex.Chat.Store.SQLite.Migrations.M20261016_badge_store_receipts
|
||||
Simplex.Chat.Store.SQLite.Migrations.M20261018_member_role_index
|
||||
other-modules:
|
||||
Paths_simplex_chat
|
||||
hs-source-dirs:
|
||||
|
||||
@@ -57,6 +57,7 @@ import Simplex.Chat.Store.Postgres.Migrations.M20260925_badge_bindings
|
||||
import Simplex.Chat.Store.Postgres.Migrations.M20261010_invite_member_via_group
|
||||
import Simplex.Chat.Store.Postgres.Migrations.M20261012_delivery_job_notification
|
||||
import Simplex.Chat.Store.Postgres.Migrations.M20261016_badge_store_receipts
|
||||
import Simplex.Chat.Store.Postgres.Migrations.M20261018_member_role_index
|
||||
import Simplex.Messaging.Agent.Store.Shared (Migration (..))
|
||||
|
||||
schemaMigrations :: [(String, Text, Maybe Text)]
|
||||
@@ -113,7 +114,8 @@ schemaMigrations =
|
||||
("20260925_badge_bindings", m20260925_badge_bindings, Just down_m20260925_badge_bindings),
|
||||
("20261010_invite_member_via_group", m20261010_invite_member_via_group, Just down_m20261010_invite_member_via_group),
|
||||
("20261012_delivery_job_notification", m20261012_delivery_job_notification, Just down_m20261012_delivery_job_notification),
|
||||
("20261016_badge_store_receipts", m20261016_badge_store_receipts, Just down_m20261016_badge_store_receipts)
|
||||
("20261016_badge_store_receipts", m20261016_badge_store_receipts, Just down_m20261016_badge_store_receipts),
|
||||
("20261018_member_role_index", m20261018_member_role_index, Just down_m20261018_member_role_index)
|
||||
]
|
||||
|
||||
-- | The list of migrations in ascending order by date
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
{-# LANGUAGE QuasiQuotes #-}
|
||||
|
||||
module Simplex.Chat.Store.Postgres.Migrations.M20261018_member_role_index where
|
||||
|
||||
import Data.Text (Text)
|
||||
import Text.RawString.QQ (r)
|
||||
|
||||
m20261018_member_role_index :: Text
|
||||
m20261018_member_role_index =
|
||||
[r|
|
||||
CREATE INDEX idx_group_members_user_id_member_role ON group_members(user_id, member_role, group_id);
|
||||
|]
|
||||
|
||||
down_m20261018_member_role_index :: Text
|
||||
down_m20261018_member_role_index =
|
||||
[r|
|
||||
DROP INDEX idx_group_members_user_id_member_role;
|
||||
|]
|
||||
@@ -2781,6 +2781,10 @@ CREATE INDEX idx_group_members_user_id_local_display_name ON test_chat_schema.gr
|
||||
|
||||
|
||||
|
||||
CREATE INDEX idx_group_members_user_id_member_role ON test_chat_schema.group_members USING btree (user_id, member_role, group_id);
|
||||
|
||||
|
||||
|
||||
CREATE INDEX idx_group_profiles_user_id ON test_chat_schema.group_profiles USING btree (user_id);
|
||||
|
||||
|
||||
|
||||
@@ -180,6 +180,7 @@ import Simplex.Chat.Store.SQLite.Migrations.M20260925_badge_bindings
|
||||
import Simplex.Chat.Store.SQLite.Migrations.M20261010_invite_member_via_group
|
||||
import Simplex.Chat.Store.SQLite.Migrations.M20261012_delivery_job_notification
|
||||
import Simplex.Chat.Store.SQLite.Migrations.M20261016_badge_store_receipts
|
||||
import Simplex.Chat.Store.SQLite.Migrations.M20261018_member_role_index
|
||||
import Simplex.Messaging.Agent.Store.Shared (Migration (..))
|
||||
|
||||
schemaMigrations :: [(String, Query, Maybe Query)]
|
||||
@@ -359,7 +360,8 @@ schemaMigrations =
|
||||
("20260925_badge_bindings", m20260925_badge_bindings, Just down_m20260925_badge_bindings),
|
||||
("20261010_invite_member_via_group", m20261010_invite_member_via_group, Just down_m20261010_invite_member_via_group),
|
||||
("20261012_delivery_job_notification", m20261012_delivery_job_notification, Just down_m20261012_delivery_job_notification),
|
||||
("20261016_badge_store_receipts", m20261016_badge_store_receipts, Just down_m20261016_badge_store_receipts)
|
||||
("20261016_badge_store_receipts", m20261016_badge_store_receipts, Just down_m20261016_badge_store_receipts),
|
||||
("20261018_member_role_index", m20261018_member_role_index, Just down_m20261018_member_role_index)
|
||||
]
|
||||
|
||||
-- | The list of migrations in ascending order by date
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
{-# LANGUAGE QuasiQuotes #-}
|
||||
|
||||
module Simplex.Chat.Store.SQLite.Migrations.M20261018_member_role_index where
|
||||
|
||||
import Database.SQLite.Simple (Query)
|
||||
import Database.SQLite.Simple.QQ (sql)
|
||||
|
||||
m20261018_member_role_index :: Query
|
||||
m20261018_member_role_index =
|
||||
[sql|
|
||||
CREATE INDEX idx_group_members_user_id_member_role ON group_members(user_id, member_role, group_id);
|
||||
|]
|
||||
|
||||
down_m20261018_member_role_index :: Query
|
||||
down_m20261018_member_role_index =
|
||||
[sql|
|
||||
DROP INDEX idx_group_members_user_id_member_role;
|
||||
|]
|
||||
@@ -6242,7 +6242,7 @@ Query:
|
||||
LEFT JOIN group_member_badge_proofs bp ON bp.group_member_id = m.group_member_id
|
||||
WHERE m.user_id = ? AND m.group_id = ? AND (m.contact_id IS NULL OR m.contact_id != ?) AND m.member_role = ?
|
||||
Plan:
|
||||
SEARCH m USING INDEX idx_group_members_group_id (user_id=? AND group_id=?)
|
||||
SEARCH m USING INDEX idx_group_members_user_id_member_role (user_id=? AND member_role=? AND group_id=?)
|
||||
SEARCH p USING INTEGER PRIMARY KEY (rowid=?)
|
||||
SEARCH c USING INDEX idx_connections_group_member_id (group_member_id=?) LEFT-JOIN
|
||||
SEARCH bp USING INTEGER PRIMARY KEY (rowid=?) LEFT-JOIN
|
||||
@@ -6265,7 +6265,7 @@ Query:
|
||||
LEFT JOIN group_member_badge_proofs bp ON bp.group_member_id = m.group_member_id
|
||||
WHERE m.user_id = ? AND m.group_id = ? AND (m.contact_id IS NULL OR m.contact_id != ?) AND m.member_role IN (?,?)
|
||||
Plan:
|
||||
SEARCH m USING INDEX idx_group_members_group_id (user_id=? AND group_id=?)
|
||||
SEARCH m USING INDEX idx_group_members_user_id_member_role (user_id=? AND member_role=? AND group_id=?)
|
||||
SEARCH p USING INTEGER PRIMARY KEY (rowid=?)
|
||||
SEARCH c USING INDEX idx_connections_group_member_id (group_member_id=?) LEFT-JOIN
|
||||
SEARCH bp USING INTEGER PRIMARY KEY (rowid=?) LEFT-JOIN
|
||||
@@ -6288,7 +6288,7 @@ Query:
|
||||
LEFT JOIN group_member_badge_proofs bp ON bp.group_member_id = m.group_member_id
|
||||
WHERE m.user_id = ? AND m.group_id = ? AND (m.contact_id IS NULL OR m.contact_id != ?) AND m.member_role IN (?,?,?)
|
||||
Plan:
|
||||
SEARCH m USING INDEX idx_group_members_group_id (user_id=? AND group_id=?)
|
||||
SEARCH m USING INDEX idx_group_members_user_id_member_role (user_id=? AND member_role=? AND group_id=?)
|
||||
SEARCH p USING INTEGER PRIMARY KEY (rowid=?)
|
||||
SEARCH c USING INDEX idx_connections_group_member_id (group_member_id=?) LEFT-JOIN
|
||||
SEARCH bp USING INTEGER PRIMARY KEY (rowid=?) LEFT-JOIN
|
||||
@@ -6311,7 +6311,7 @@ Query:
|
||||
LEFT JOIN group_member_badge_proofs bp ON bp.group_member_id = m.group_member_id
|
||||
WHERE m.user_id = ? AND m.group_id = ? AND m.contact_id IS DISTINCT FROM ? AND m.member_role = ?
|
||||
Plan:
|
||||
SEARCH m USING INDEX idx_group_members_group_id (user_id=? AND group_id=?)
|
||||
SEARCH m USING INDEX idx_group_members_user_id_member_role (user_id=? AND member_role=? AND group_id=?)
|
||||
SEARCH p USING INTEGER PRIMARY KEY (rowid=?)
|
||||
SEARCH c USING INDEX idx_connections_group_member_id (group_member_id=?) LEFT-JOIN
|
||||
SEARCH bp USING INTEGER PRIMARY KEY (rowid=?) LEFT-JOIN
|
||||
|
||||
@@ -1584,6 +1584,11 @@ CREATE INDEX idx_badge_store_receipts_user ON badge_store_receipts(user_id);
|
||||
CREATE UNIQUE INDEX idx_badge_purchases_store_receipt ON badge_purchases(
|
||||
badge_store_receipt_id
|
||||
);
|
||||
CREATE INDEX idx_group_members_user_id_member_role ON group_members(
|
||||
user_id,
|
||||
member_role,
|
||||
group_id
|
||||
);
|
||||
CREATE TRIGGER on_group_members_insert_update_summary
|
||||
AFTER INSERT ON group_members
|
||||
FOR EACH ROW
|
||||
|
||||
Reference in new issue
Block a user