[CORE][DATABASE] Another approach to semi-join in the inboxnoticestream query

Compared to the solution with INNER JOIN this seems to have better performance
as there is no need to deduplicate the subquery result before use.
This commit is contained in:
Alexei Sorokin 2020-06-10 14:21:47 +03:00
parent 0eec6fcfb6
commit ef17f3ea7d

View File

@ -93,22 +93,25 @@ class RawInboxNoticeStream extends FullNoticeStream
// Subscription:: is a table of subscriptions (every user is subscribed to themselves)
$notice->_join .= sprintf(
"\n" . <<<'END'
INNER JOIN (
(SELECT id FROM notice
WHERE profile_id
IN (SELECT subscribed FROM subscription WHERE subscriber = %1$d))
UNION
(SELECT notice_id AS id FROM reply WHERE profile_id = %1$d)
UNION
(SELECT notice_id AS id FROM attention WHERE profile_id = %1$d)
UNION
(SELECT notice_id AS id FROM group_inbox INNER JOIN group_member USING (group_id)
WHERE group_member.profile_id = %1$d)
LEFT JOIN (
SELECT notice.id
FROM notice INNER JOIN subscription
ON notice.profile_id = subscription.subscribed
WHERE subscription.subscriber = %1$d
UNION ALL
SELECT notice_id AS id FROM reply WHERE profile_id = %1$d
UNION ALL
SELECT notice_id AS id FROM attention WHERE profile_id = %1$d
UNION ALL
SELECT notice_id AS id FROM group_inbox INNER JOIN group_member USING (group_id)
WHERE group_member.profile_id = %1$d
) AS t1 USING (id)
END,
$this->target->getID()
);
$notice->whereAdd('t1.id IS NOT NULL');
$notice->whereAdd(sprintf(
"notice.created > TIMESTAMP '%s'",
$notice->escape($this->target->created)