Increase perf of `get_auth_chain_ids` used in state res v2. (#6937)

We do this by moving the recursive query to be fully in the DB.
pull/6945/head
Erik Johnston 2020-02-18 15:39:09 +00:00 committed by GitHub
parent 818def8248
commit 8a380d0fe2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 24 additions and 0 deletions

1
changelog.d/6937.misc Normal file
View File

@ -0,0 +1 @@
Increase perf of `get_auth_chain_ids` used in state res v2.

View File

@ -26,6 +26,7 @@ from synapse.storage._base import SQLBaseStore, make_in_list_sql_clause
from synapse.storage.data_stores.main.events_worker import EventsWorkerStore from synapse.storage.data_stores.main.events_worker import EventsWorkerStore
from synapse.storage.data_stores.main.signatures import SignatureWorkerStore from synapse.storage.data_stores.main.signatures import SignatureWorkerStore
from synapse.storage.database import Database from synapse.storage.database import Database
from synapse.storage.engines import PostgresEngine
from synapse.util.caches.descriptors import cached from synapse.util.caches.descriptors import cached
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -61,6 +62,28 @@ class EventFederationWorkerStore(EventsWorkerStore, SignatureWorkerStore, SQLBas
) )
def _get_auth_chain_ids_txn(self, txn, event_ids, include_given): def _get_auth_chain_ids_txn(self, txn, event_ids, include_given):
if isinstance(self.database_engine, PostgresEngine):
# For efficiency we make the database do this if we can.
sql = """
WITH RECURSIVE auth_chain(event_id) AS (
SELECT auth_id FROM event_auth WHERE event_id = ANY(?)
UNION
SELECT auth_id FROM event_auth
INNER JOIN auth_chain USING (event_id)
)
SELECT event_id FROM auth_chain
"""
txn.execute(sql, (list(event_ids),))
results = set(event_id for event_id, in txn)
if include_given:
results.update(event_ids)
return list(results)
# Database doesn't necessarily support recursive CTE, so we fall
# back to do doing it manually.
if include_given: if include_given:
results = set(event_ids) results = set(event_ids)
else: else: