50% speed up in notifications query with many items

This commit is contained in:
keyan 2023-09-29 19:12:23 -05:00
parent f2b1c321c2
commit 1f0a4e0729

View File

@ -75,75 +75,59 @@ export default {
// Replies // Replies
itemDrivenQueries.push( itemDrivenQueries.push(
`SELECT DISTINCT "Item".id::TEXT, "Item".created_at AS "sortTime", NULL::BIGINT as "earnedSats", `SELECT "Item".*, "Item".created_at AS "sortTime", 'Reply' AS type
'Reply' AS type FROM "Item"
FROM "Item" JOIN "Item" p ON ${meFull.noteAllDescendants ? '"Item".path <@ p.path' : '"Item"."parentId" = p.id'}
JOIN "Item" p ON ${meFull.noteAllDescendants ? '"Item".path <@ p.path' : '"Item"."parentId" = p.id'} ${whereClause(
${whereClause( 'p."userId" = $1',
'p."userId" = $1', '"Item"."userId" <> $1'
'"Item"."userId" <> $1', )}
'"Item".created_at <= $2', ORDER BY "sortTime" DESC
await filterClause(me, models), LIMIT ${LIMIT}+$3`
muteClause(me)
)}
ORDER BY "sortTime" DESC
LIMIT ${LIMIT}+$3`
) )
// Thread subscriptions // Thread subscriptions
itemDrivenQueries.push( itemDrivenQueries.push(
`SELECT DISTINCT "Item".id::TEXT, "Item".created_at AS "sortTime", NULL::BIGINT as "earnedSats", `SELECT "Item".*, "Item".created_at AS "sortTime", 'Reply' AS type
'Reply' AS type FROM "ThreadSubscription"
FROM "ThreadSubscription" JOIN "Item" p ON "ThreadSubscription"."itemId" = p.id
JOIN "Item" p ON "ThreadSubscription"."itemId" = p.id JOIN "Item" ON ${meFull.noteAllDescendants ? '"Item".path <@ p.path' : '"Item"."parentId" = p.id'}
JOIN "Item" ON ${meFull.noteAllDescendants ? '"Item".path <@ p.path' : '"Item"."parentId" = p.id'} ${whereClause(
${whereClause( '"ThreadSubscription"."userId" = $1',
'"ThreadSubscription"."userId" = $1', '"Item"."userId" <> $1',
'"Item"."userId" <> $1', '"Item".created_at >= "ThreadSubscription".created_at',
'"Item".created_at <= $2', '"Item"."parentId" IS NOT NULL'
'"Item".created_at >= "ThreadSubscription".created_at', )}
'"Item"."parentId" IS NOT NULL', ORDER BY "sortTime" DESC
await filterClause(me, models), LIMIT ${LIMIT}+$3`
muteClause(me)
)}
ORDER BY "sortTime" DESC
LIMIT ${LIMIT}+$3`
) )
// User subscriptions // User subscriptions
// Only include posts or comments created after the corresponding subscription was enabled, not _all_ from history // Only include posts or comments created after the corresponding subscription was enabled, not _all_ from history
itemDrivenQueries.push( itemDrivenQueries.push(
`SELECT DISTINCT "Item".id::TEXT, "Item".created_at AS "sortTime", NULL::BIGINT as "earnedSats", `SELECT "Item".*, "Item".created_at AS "sortTime", 'FollowActivity' AS type
'FollowActivity' AS type FROM "Item"
FROM "Item" JOIN "UserSubscription" ON "Item"."userId" = "UserSubscription"."followeeId"
JOIN "UserSubscription" ON "Item"."userId" = "UserSubscription"."followeeId" ${whereClause(
${whereClause( '"UserSubscription"."followerId" = $1',
'"UserSubscription"."followerId" = $1', `(
'"Item".created_at <= $2', ("Item"."parentId" IS NULL AND "UserSubscription"."postsSubscribedAt" IS NOT NULL AND "Item".created_at >= "UserSubscription"."postsSubscribedAt")
`( OR ("Item"."parentId" IS NOT NULL AND "UserSubscription"."commentsSubscribedAt" IS NOT NULL AND "Item".created_at >= "UserSubscription"."commentsSubscribedAt")
("Item"."parentId" IS NULL AND "UserSubscription"."postsSubscribedAt" IS NOT NULL AND "Item".created_at >= "UserSubscription"."postsSubscribedAt") )`
OR ("Item"."parentId" IS NOT NULL AND "UserSubscription"."commentsSubscribedAt" IS NOT NULL AND "Item".created_at >= "UserSubscription"."commentsSubscribedAt") )}
)`, ORDER BY "sortTime" DESC
await filterClause(me, models), LIMIT ${LIMIT}+$3`
muteClause(me)
)}
ORDER BY "sortTime" DESC
LIMIT ${LIMIT}+$3`
) )
// mentions // mentions
if (meFull.noteMentions) { if (meFull.noteMentions) {
itemDrivenQueries.push( itemDrivenQueries.push(
`SELECT "Item".id::TEXT, "Mention".created_at AS "sortTime", NULL as "earnedSats", `SELECT "Item".*, "Mention".created_at AS "sortTime", 'Mention' AS type
'Mention' AS type
FROM "Mention" FROM "Mention"
JOIN "Item" ON "Mention"."itemId" = "Item".id JOIN "Item" ON "Mention"."itemId" = "Item".id
${whereClause( ${whereClause(
'"Mention"."userId" = $1', '"Mention"."userId" = $1',
'"Mention".created_at <= $2', '"Item"."userId" <> $1'
'"Item"."userId" <> $1',
await filterClause(me, models),
muteClause(me)
)} )}
ORDER BY "sortTime" DESC ORDER BY "sortTime" DESC
LIMIT ${LIMIT}+$3` LIMIT ${LIMIT}+$3`
@ -152,18 +136,21 @@ export default {
// Inner union to de-dupe item-driven notifications // Inner union to de-dupe item-driven notifications
queries.push( queries.push(
// Only record per item ID // Only record per item ID
`(SELECT DISTINCT ON (id) * `(
SELECT DISTINCT ON (id) "Item".id::TEXT, "Item"."sortTime", NULL::BIGINT AS "earnedSats", "Item".type
FROM ( FROM (
SELECT * ${itemDrivenQueries.map(q => `(${q})`).join(' UNION ALL ')}
FROM ( ) as "Item"
${itemDrivenQueries.map(q => `(${q})`).join(' UNION ALL ')} ${whereClause(
) as inner_union '"Item".created_at <= $2',
ORDER BY id ASC, CASE await filterClause(me, models),
WHEN type = 'Mention' THEN 1 muteClause(me))}
WHEN type = 'Reply' THEN 2 ORDER BY id ASC, CASE
WHEN type = 'FollowActivity' THEN 3 WHEN type = 'Mention' THEN 1
END ASC WHEN type = 'Reply' THEN 2
) as ordered_unioned)` WHEN type = 'FollowActivity' THEN 3
END ASC
)`
) )
queries.push( queries.push(