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,16 +75,12 @@ 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',
await filterClause(me, models),
muteClause(me)
)} )}
ORDER BY "sortTime" DESC ORDER BY "sortTime" DESC
LIMIT ${LIMIT}+$3` LIMIT ${LIMIT}+$3`
@ -92,19 +88,15 @@ export default {
// 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 <= $2',
'"Item".created_at >= "ThreadSubscription".created_at', '"Item".created_at >= "ThreadSubscription".created_at',
'"Item"."parentId" IS NOT NULL', '"Item"."parentId" IS NOT NULL'
await filterClause(me, models),
muteClause(me)
)} )}
ORDER BY "sortTime" DESC ORDER BY "sortTime" DESC
LIMIT ${LIMIT}+$3` LIMIT ${LIMIT}+$3`
@ -113,19 +105,15 @@ export default {
// 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") ("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") OR ("Item"."parentId" IS NOT NULL AND "UserSubscription"."commentsSubscribedAt" IS NOT NULL AND "Item".created_at >= "UserSubscription"."commentsSubscribedAt")
)`, )`
await filterClause(me, models),
muteClause(me)
)} )}
ORDER BY "sortTime" DESC ORDER BY "sortTime" DESC
LIMIT ${LIMIT}+$3` LIMIT ${LIMIT}+$3`
@ -134,16 +122,12 @@ export default {
// 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) * `(
FROM ( SELECT DISTINCT ON (id) "Item".id::TEXT, "Item"."sortTime", NULL::BIGINT AS "earnedSats", "Item".type
SELECT *
FROM ( FROM (
${itemDrivenQueries.map(q => `(${q})`).join(' UNION ALL ')} ${itemDrivenQueries.map(q => `(${q})`).join(' UNION ALL ')}
) as inner_union ) as "Item"
${whereClause(
'"Item".created_at <= $2',
await filterClause(me, models),
muteClause(me))}
ORDER BY id ASC, CASE ORDER BY id ASC, CASE
WHEN type = 'Mention' THEN 1 WHEN type = 'Mention' THEN 1
WHEN type = 'Reply' THEN 2 WHEN type = 'Reply' THEN 2
WHEN type = 'FollowActivity' THEN 3 WHEN type = 'FollowActivity' THEN 3
END ASC END ASC
) as ordered_unioned)` )`
) )
queries.push( queries.push(