Files
synapse/changelog.d/18582.bugfix
reivilibre bfb3a6e700 Improve performance of device deletion by adding missing index. (#18582)
<ol>
<li>

Reorder columns in `event_txn_id_device_id_txn_id` index \
This now satisfies the foreign key on `(user_id, device_id)` making
reverse lookups, as needed for device deletions, more efficient.

This improves device deletion performance by on the order of 8 to 10×
on matrix.org.


</li>
</ol>


Rationale:

## On the `event_txn_id_device_id` table:

We currently have this index:
```sql
-- This ensures that there is only one mapping per (room_id, user_id, device_id, txn_id) tuple.
CREATE UNIQUE INDEX IF NOT EXISTS event_txn_id_device_id_txn_id 
    ON event_txn_id_device_id(room_id, user_id, device_id, txn_id);
```

The main way we use this table is
```python
        return await self.db_pool.simple_select_one_onecol(
            table="event_txn_id_device_id",
            keyvalues={
                "room_id": room_id,
                "user_id": user_id,
                "device_id": device_id,
                "txn_id": txn_id,
            },
            retcol="event_id",
            allow_none=True,
            desc="get_event_id_from_transaction_id_and_device_id",
        )
```

But this foreign key is relatively unsupported, making deletions in
the devices table inefficient (full index scan on the above index):
```sql
    FOREIGN KEY (user_id, device_id)
        REFERENCES devices (user_id, device_id) ON DELETE CASCADE
```

I propose re-ordering the columns in that index to: `(user_id,
device_id, room_id, txn_id)` (by replacing it).

That way the foreign key back-check can rely on the prefix of this
index, but it's still useful for the original purpose it was made for.

It doesn't take any extra disk space and does not harm write performance
(because the same amount of writing work needs to be performed).

---------

Signed-off-by: Olivier 'reivilibre <oliverw@matrix.org>
2025-06-30 10:36:12 +01:00

1 line
63 B
Plaintext

Improve performance of device deletion by adding missing index.