fix(notifications): cost the followed-accounts subselect once

Wrap the followed ap_ids subselect in keep_following_or_not_domain_blocked
in ARRAY(...) so it becomes an InitPlan. As a plain subselect the planner
charged its startup per rescan of the actor lookup, which could make
Notification.for_user pick a plan that scans every active user per row.
This commit is contained in:
Lain Soykaf 2026-09-02 13:42:48 +04:00
commit 635bc19ac8
No known key found for this signature in database
3 changed files with 24 additions and 2 deletions

View file

@ -258,10 +258,16 @@ defmodule Pleroma.FollowingRelationship do
[_, user_actor: user_actor],
fragment(
# "(actor's domain NOT in domain_blocks) OR (actor IS in followed AP IDs)"
#
# ARRAY(SELECT ...) makes the followed-ids lookup an InitPlan that is
# evaluated and costed once. As a plain subselect, the planner charges
# its startup cost on every rescan of the actor lookup, which inflates
# the cost of the index plan enough for it to lose to a plan that
# materialises every active user for every candidate row.
"""
NOT (substring(? from '.*://([^/]*)') = ANY(?)) OR
? = ANY(SELECT ap_id FROM users AS u INNER JOIN following_relationships AS fr
ON u.id = fr.following_id WHERE fr.follower_id = ? AND fr.state = ?)
? = ANY(ARRAY(SELECT ap_id FROM users AS u INNER JOIN following_relationships AS fr
ON u.id = fr.following_id WHERE fr.follower_id = ? AND fr.state = ?))
""",
user_actor.ap_id,
^user.domain_blocks,