[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 committed by Diogo Peralta Cordeiro
parent ed4cc01b2f
commit a93c38a9af

View File

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