diff --git a/changelog.d/18851.bugfix b/changelog.d/18851.bugfix new file mode 100644 index 000000000..4c2715456 --- /dev/null +++ b/changelog.d/18851.bugfix @@ -0,0 +1 @@ +Improve database performance of [MSC4293](https://github.com/matrix-org/matrix-spec-proposals/pull/4293) - Redact on Kick/Ban. \ No newline at end of file diff --git a/synapse/storage/databases/main/events_worker.py b/synapse/storage/databases/main/events_worker.py index 7f015aa22..321773d8a 100644 --- a/synapse/storage/databases/main/events_worker.py +++ b/synapse/storage/databases/main/events_worker.py @@ -81,6 +81,7 @@ from synapse.storage.database import ( DatabasePool, LoggingDatabaseConnection, LoggingTransaction, + make_tuple_in_list_sql_clause, ) from synapse.storage.types import Cursor from synapse.storage.util.id_generators import ( @@ -1617,21 +1618,28 @@ class EventsWorkerStore(SQLBaseStore): # likely that some of these events may be for the same room/user combo, in # which case we don't need to do redundant queries to_check_set = set(to_check) - for room_and_user in to_check_set: - room_redactions_sql = "SELECT redacting_event_id, redact_end_ordering FROM room_ban_redactions WHERE room_id = ? and user_id = ?" - txn.execute(room_redactions_sql, room_and_user) - - res = txn.fetchone() - # we have a redaction for a room, user_id combo - apply it to matching events - if not res: - continue + room_redaction_sql = "SELECT room_id, user_id, redacting_event_id, redact_end_ordering FROM room_ban_redactions WHERE " + ( + in_list_clause, + room_redaction_args, + ) = make_tuple_in_list_sql_clause( + self.database_engine, ("room_id", "user_id"), to_check_set + ) + txn.execute(room_redaction_sql + in_list_clause, room_redaction_args) + for ( + returned_room_id, + returned_user_id, + redacting_event_id, + redact_end_ordering, + ) in txn: for e_row in events: e_json = json.loads(e_row.json) room_id = e_json.get("room_id") user_id = e_json.get("sender") + room_and_user = (returned_room_id, returned_user_id) + # check if we have a redaction match for this room, user combination if room_and_user != (room_id, user_id): continue - redacting_event_id, redact_end_ordering = res if redact_end_ordering: # Avoid redacting any events arriving *after* the membership event which # ends an active redaction - note that this will always redact