Объяснение кажется простым. Вы объединяете две таблицы, Alerts
и SubscriptionFeed
. И вы хотите увидеть двадцать строк результатов с самыми высокими датами. Каждая SubscriptionFeed
строка принадлежит Alerts
строке, но не каждая Alerts
строка обязательно имеет SubscriptionFeed
строки.
Итак, если вам нужны последние SubscriptionFeed
строки, это легко: возьмите последние 20 SubscriptionFeed
строк (из индекса), соедините их 20 Alerts
строк, и все готово.
Если вместо этого требуется последняя версия Alerts
, СУБД возьмет последнюю строку Alerts
, объединит все ее подписки, проверит, получило ли она уже двадцать строк, если нет, то снова возьмет следующую строку Alerts
присоединитесь ко всем его подпискам, проверьте, достигнуты ли двадцать строк, и так далее. Что ж, СУБД может использовать другой алгоритм, но он никогда не будет таким простым, как для последних SubscriptionFeed
.
Вот и все. Маловероятно, что мы можем получить запрос Alerts
почти так же быстро, как запрос SubscriptionFeed
. Но мы можем подумать о том, как помочь СУБД в доступе к строкам: Ваш существующий индекс на Alerts(createdAt DESC, id DESC)
помогает СУБД быстро находить самые последние строки Alerts
. Чтобы быстро получить их SubscriptionFeed
, вам нужно индексировать SubscriptionFeed(alertId)
. (Ну, может быть, у вас уже есть, учитывая, что SubscriptionFeed.alertId
ссылки Alerts.id
.)
Кроме того, вы можете предоставить покрывающие индексы, содержащие все столбцы из таблицы, которую вы используете в своем запросе (то есть добавить другие столбцы к уже упомянутым индексам), например ::
create index idx on SubscriptionFeed(alertId, name);