diff --git a/changelog.d/17946.misc b/changelog.d/17946.misc
new file mode 100644
index 0000000000000000000000000000000000000000..3520a75f58d16f0b1e6dbc253e1c2789d89368b5
--- /dev/null
+++ b/changelog.d/17946.misc
@@ -0,0 +1 @@
+Speed up slow initial sliding syncs on large servers.
diff --git a/synapse/_scripts/synapse_port_db.py b/synapse/_scripts/synapse_port_db.py
index 31639d366ecaee1efc8fa1d7cbd10c6245667fd5..d8f6f8ebdc3c4ba5bed15200e5a77154b24b591a 100755
--- a/synapse/_scripts/synapse_port_db.py
+++ b/synapse/_scripts/synapse_port_db.py
@@ -88,6 +88,7 @@ from synapse.storage.databases.main.relations import RelationsWorkerStore
 from synapse.storage.databases.main.room import RoomBackgroundUpdateStore
 from synapse.storage.databases.main.roommember import RoomMemberBackgroundUpdateStore
 from synapse.storage.databases.main.search import SearchBackgroundUpdateStore
+from synapse.storage.databases.main.sliding_sync import SlidingSyncStore
 from synapse.storage.databases.main.state import MainStateBackgroundUpdateStore
 from synapse.storage.databases.main.stats import StatsStore
 from synapse.storage.databases.main.user_directory import (
@@ -255,6 +256,7 @@ class Store(
     ReceiptsBackgroundUpdateStore,
     RelationsWorkerStore,
     EventFederationWorkerStore,
+    SlidingSyncStore,
 ):
     def execute(self, f: Callable[..., R], *args: Any, **kwargs: Any) -> Awaitable[R]:
         return self.db_pool.runInteraction(f.__name__, f, *args, **kwargs)
diff --git a/synapse/storage/databases/main/sliding_sync.py b/synapse/storage/databases/main/sliding_sync.py
index 7b357c1ffea400554c814bd722a61e446bd50956..874dfdcb77a4508b94db7d29c528b37e6a02f6d8 100644
--- a/synapse/storage/databases/main/sliding_sync.py
+++ b/synapse/storage/databases/main/sliding_sync.py
@@ -21,7 +21,11 @@ import attr
 from synapse.api.errors import SlidingSyncUnknownPosition
 from synapse.logging.opentracing import log_kv
 from synapse.storage._base import SQLBaseStore, db_to_json
-from synapse.storage.database import LoggingTransaction
+from synapse.storage.database import (
+    DatabasePool,
+    LoggingDatabaseConnection,
+    LoggingTransaction,
+)
 from synapse.types import MultiWriterStreamToken, RoomStreamToken
 from synapse.types.handlers.sliding_sync import (
     HaveSentRoom,
@@ -35,12 +39,28 @@ from synapse.util import json_encoder
 from synapse.util.caches.descriptors import cached
 
 if TYPE_CHECKING:
+    from synapse.server import HomeServer
     from synapse.storage.databases.main import DataStore
 
 logger = logging.getLogger(__name__)
 
 
 class SlidingSyncStore(SQLBaseStore):
+    def __init__(
+        self,
+        database: DatabasePool,
+        db_conn: LoggingDatabaseConnection,
+        hs: "HomeServer",
+    ):
+        super().__init__(database, db_conn, hs)
+
+        self.db_pool.updates.register_background_index_update(
+            update_name="sliding_sync_connection_room_configs_required_state_id_idx",
+            index_name="sliding_sync_connection_room_configs_required_state_id_idx",
+            table="sliding_sync_connection_room_configs",
+            columns=("required_state_id",),
+        )
+
     async def get_latest_bump_stamp_for_room(
         self,
         room_id: str,
diff --git a/synapse/storage/schema/main/delta/88/05_sliding_sync_room_config_index.sql b/synapse/storage/schema/main/delta/88/05_sliding_sync_room_config_index.sql
new file mode 100644
index 0000000000000000000000000000000000000000..7b2e18a84bce1947ab18ad1dcca9170f5e99ff0b
--- /dev/null
+++ b/synapse/storage/schema/main/delta/88/05_sliding_sync_room_config_index.sql
@@ -0,0 +1,20 @@
+--
+-- This file is licensed under the Affero General Public License (AGPL) version 3.
+--
+-- Copyright (C) 2024 New Vector, Ltd
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Affero General Public License as
+-- published by the Free Software Foundation, either version 3 of the
+-- License, or (at your option) any later version.
+--
+-- See the GNU Affero General Public License for more details:
+-- <https://www.gnu.org/licenses/agpl-3.0.html>.
+
+
+-- Add an index on sliding_sync_connection_room_configs(required_state_id), so
+-- that when we delete entries in `sliding_sync_connection_required_state` it's
+-- efficient for Postgres to check they've been deleted from
+-- `sliding_sync_connection_room_configs` too
+INSERT INTO background_updates (ordering, update_name, progress_json) VALUES
+    (8805, 'sliding_sync_connection_room_configs_required_state_id_idx', '{}');