dbprune: shortcut array activity search

This brought down query costs from 7,953,740.90 to 47,600.97
This commit is contained in:
Oneric 2024-05-15 01:20:27 +02:00
parent 6e7cbf1885
commit 1d4c212441
2 changed files with 19 additions and 1 deletions

View file

@ -36,6 +36,19 @@ def prune_orphaned_activities(limit \\ 0) when is_number(limit) do
"" ""
end end
# Activities can either refer to a single object id, and array of object ids
# or contain an inlined object (at least after going through our normalisation)
#
# Flag is the only type we support with an array (and always has arrays).
# Update the only one with inlined objects.
#
# We already regularly purge old Delete, Undo, Update and Remove and if
# rejected Follow requests anyway; no need to explicitly deal with those here.
#
# Since theres an index on types and there are typically only few Flag
# activites, its _much_ faster to utilise the index. To avoid accidentally
# deleting useful activities should more types be added, keep typeof for singles.
# Prune activities who link to a single object # Prune activities who link to a single object
{:ok, %{:num_rows => del_single}} = {:ok, %{:num_rows => del_single}} =
""" """
@ -61,7 +74,8 @@ def prune_orphaned_activities(limit \\ 0) when is_number(limit) do
delete from public.activities delete from public.activities
where id in ( where id in (
select a.id from public.activities a select a.id from public.activities a
join json_array_elements_text((a."data" -> 'object')::json) as j on jsonb_typeof(a."data" -> 'object') = 'array' join json_array_elements_text((a."data" -> 'object')::json) as j
on a.data->>'type' = 'Flag'
left join public.objects o on j.value = o.data ->> 'id' left join public.objects o on j.value = o.data ->> 'id'
left join public.activities a2 on j.value = a2.data ->> 'id' left join public.activities a2 on j.value = a2.data ->> 'id'
left join public.users u on j.value = u.ap_id left join public.users u on j.value = u.ap_id

View file

@ -478,6 +478,7 @@ test "it prunes orphaned activities with prune_orphaned_activities when the obje
|> Map.merge(%{ |> Map.merge(%{
local: false, local: false,
data: %{ data: %{
"type" => "Flag",
"id" => "remote_activity_existing_object", "id" => "remote_activity_existing_object",
"object" => ["non_ existing_object", "existing_object"] "object" => ["non_ existing_object", "existing_object"]
} }
@ -488,6 +489,7 @@ test "it prunes orphaned activities with prune_orphaned_activities when the obje
|> Map.merge(%{ |> Map.merge(%{
local: false, local: false,
data: %{ data: %{
"type" => "Flag",
"id" => "remote_activity_existing_actor", "id" => "remote_activity_existing_actor",
"object" => ["non_ existing_object", "existing_actor"] "object" => ["non_ existing_object", "existing_actor"]
} }
@ -498,6 +500,7 @@ test "it prunes orphaned activities with prune_orphaned_activities when the obje
|> Map.merge(%{ |> Map.merge(%{
local: false, local: false,
data: %{ data: %{
"type" => "Flag",
"id" => "remote_activity_existing_activity", "id" => "remote_activity_existing_activity",
"object" => ["non_ existing_object", "remote_activity_existing_actor"] "object" => ["non_ existing_object", "remote_activity_existing_actor"]
} }
@ -508,6 +511,7 @@ test "it prunes orphaned activities with prune_orphaned_activities when the obje
|> Map.merge(%{ |> Map.merge(%{
local: false, local: false,
data: %{ data: %{
"type" => "Flag",
"id" => "remote_activity_without_existing_referenced_object", "id" => "remote_activity_without_existing_referenced_object",
"object" => ["owo", "whats_this"] "object" => ["owo", "whats_this"]
} }