diff options
| author | Hazelnoot <acomputerdog@gmail.com> | 2025-06-05 00:35:22 -0400 |
|---|---|---|
| committer | Hazelnoot <acomputerdog@gmail.com> | 2025-06-05 00:35:22 -0400 |
| commit | 232894cd86a8d7ff5a4be39a0cd9bfec851df77b (patch) | |
| tree | 74e153b3a65e2981a73ee1a47c24d776cbae6d7c /packages/backend/src/server/api/endpoints/notes | |
| parent | use index when checking visibleUserIds and mentions in generateVisibilityQuery (diff) | |
| download | sharkey-232894cd86a8d7ff5a4be39a0cd9bfec851df77b.tar.gz sharkey-232894cd86a8d7ff5a4be39a0cd9bfec851df77b.tar.bz2 sharkey-232894cd86a8d7ff5a4be39a0cd9bfec851df77b.zip | |
fix performance regression in home timeline
Diffstat (limited to 'packages/backend/src/server/api/endpoints/notes')
| -rw-r--r-- | packages/backend/src/server/api/endpoints/notes/timeline.ts | 73 |
1 files changed, 18 insertions, 55 deletions
diff --git a/packages/backend/src/server/api/endpoints/notes/timeline.ts b/packages/backend/src/server/api/endpoints/notes/timeline.ts index a23a61373e..d898748ac7 100644 --- a/packages/backend/src/server/api/endpoints/notes/timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/timeline.ts @@ -140,64 +140,27 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- } private async getFromDb(ps: { untilId: string | null; sinceId: string | null; limit: number; withFiles: boolean; withRenotes: boolean; withBots: boolean; }, me: MiLocalUser) { - const followees = await this.userFollowingService.getFollowees(me.id); - const followingChannels = await this.channelFollowingsRepository.find({ - where: { - followerId: me.id, - }, - }); - //#region Construct query const query = this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'), ps.sinceId, ps.untilId) .innerJoinAndSelect('note.user', 'user') .leftJoinAndSelect('note.reply', 'reply') .leftJoinAndSelect('note.renote', 'renote') - .leftJoinAndSelect('reply.user', 'replyUser', 'replyUser.id = note.replyUserId') - .leftJoinAndSelect('renote.user', 'renoteUser', 'renoteUser.id = note.renoteUserId'); - - if (followees.length > 0 && followingChannels.length > 0) { - // ユーザー・チャンネルともにフォローあり - const meOrFolloweeIds = [me.id, ...followees.map(f => f.followeeId)]; - const followingChannelIds = followingChannels.map(x => x.followeeId); - query.andWhere(new Brackets(qb => { - qb - .where(new Brackets(qb2 => { - qb2 - .where('note.userId IN (:...meOrFolloweeIds)', { meOrFolloweeIds: meOrFolloweeIds }) - .andWhere('note.channelId IS NULL'); - })) - .orWhere('note.channelId IN (:...followingChannelIds)', { followingChannelIds }); - })); - } else if (followees.length > 0) { - // ユーザーフォローのみ(チャンネルフォローなし) - const meOrFolloweeIds = [me.id, ...followees.map(f => f.followeeId)]; - query - .andWhere('note.channelId IS NULL') - .andWhere('note.userId IN (:...meOrFolloweeIds)', { meOrFolloweeIds: meOrFolloweeIds }); - } else if (followingChannels.length > 0) { - // チャンネルフォローのみ(ユーザーフォローなし) - const followingChannelIds = followingChannels.map(x => x.followeeId); - query.andWhere(new Brackets(qb => { - qb - .where('note.channelId IN (:...followingChannelIds)', { followingChannelIds }) - .orWhere('note.userId = :meId', { meId: me.id }); - })); - } else { - // フォローなし - query - .andWhere('note.channelId IS NULL') - .andWhere('note.userId = :meId', { meId: me.id }); - } - - query.andWhere(new Brackets(qb => { - qb - .where('note.replyId IS NULL') // 返信ではない - .orWhere(new Brackets(qb => { - qb // 返信だけど投稿者自身への返信 - .where('note.replyId IS NOT NULL') - .andWhere('note.replyUserId = note.userId'); - })); - })); + .leftJoinAndSelect('reply.user', 'replyUser') + .leftJoinAndSelect('renote.user', 'renoteUser') + // 1. in a channel I follow, 2. my own post, 3. by a user I follow + .andWhere(new Brackets(qb => this.queryService + .orFollowingChannel(qb, ':meId', 'note.channelId') + .orWhere(':meId = note.userId') + .orWhere(new Brackets(qb2 => this.queryService + .andFollowingUser(qb2, ':meId', 'note.userId') + .andWhere('note.channelId IS NULL'))), + )) + // 1. Not a reply, 2. a self-reply + .andWhere(new Brackets(qb => qb + .orWhere('note.replyId IS NULL') // 返信ではない + .orWhere('note.replyUserId = note.userId'))) + .setParameters({ meId: me.id }) + .limit(ps.limit); this.queryService.generateVisibilityQuery(query, me); this.queryService.generateBlockedHostQueryForNote(query); @@ -212,11 +175,11 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- if (!ps.withRenotes) { this.queryService.generateExcludedRenotesQueryForNotes(query); - } else if (me) { + } else { this.queryService.generateMutedUserRenotesQueryForNotes(query, me); } //#endregion - return await query.limit(ps.limit).getMany(); + return await query.getMany(); } } |