From 347344287540a663d2ea4e7414a6e6e9bc8e6501 Mon Sep 17 00:00:00 2001
From: Norm <normandy@biribiri.dev>
Date: Sat, 22 Jul 2023 14:10:37 +0000
Subject: [PATCH] backend: improve removeMentionedRemoteUsersColumn revert
 query (#403)

This is an optimized version made by Volpeon that should run faster if
the instance has a lot of notes.

See <https://is-a.wyvern.rip/notes/9habqldl6j> for a comparison of the
EXPLAIN ANALYZE of the old and new queries.

Co-authored-by: Volpeon <git@volpeon.ink>

Reviewed-on: https://akkoma.dev/FoundKeyGang/FoundKey/pulls/403
---
 .../1710688552234-remove-mentioned-users-column.ts     | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/packages/backend/src/migration/1710688552234-remove-mentioned-users-column.ts b/packages/backend/src/migration/1710688552234-remove-mentioned-users-column.ts
index f2730f3cde..e2b1eed950 100644
--- a/packages/backend/src/migration/1710688552234-remove-mentioned-users-column.ts
+++ b/packages/backend/src/migration/1710688552234-remove-mentioned-users-column.ts
@@ -13,8 +13,16 @@ export class RemoveMentionedUsersColumn1710688552234
 		await queryRunner.query(
 			`ALTER TABLE "note" ADD "mentionedRemoteUsers" TEXT NOT NULL DEFAULT '[]'::text`,
 		);
+		await queryRunner.query(`CREATE TEMP TABLE IF NOT EXISTS "temp_mentions" AS
+			SELECT "id", "url", "uri", "username", "host"
+			FROM "user"
+			JOIN "user_profile" ON "user"."id" = "user_profile". "userId" WHERE "user"."host" IS NOT NULL`);
 		await queryRunner.query(
-			`UPDATE "note" SET "mentionedRemoteUsers" = (SELECT COALESCE(json_agg(row_to_json("data"))::text, '[]') FROM (SELECT "url", "uri", "username", "host" FROM "user" JOIN "user_profile" ON "user"."id" = "user_profile". "userId" WHERE "user"."host" IS NOT NULL AND "user"."id" = ANY("note"."mentions")) AS "data")`,
+			`CREATE UNIQUE INDEX "temp_mentions_id" ON "temp_mentions"("id")`,
 		);
+		await queryRunner.query(`UPDATE "note" SET "mentionedRemoteUsers" = (
+			SELECT COALESCE(json_agg(row_to_json("data")::jsonb - 'id')::text, '[]') FROM "temp_mentions" AS "data"
+			WHERE "data"."id" = ANY("note"."mentions")
+			)`);
 	}
 }