Order by в запросе вычисляет rating для всей таблицы, а потом делает сортировку.
А как вы ещё предлагаете считать topN? Откуда знать, что где-то в середине множества данных не найдётся новой top1 величины? Конечно надо найти все величины и затем из них выбрать топ.
coalesce, джойны, сортировки - всё фигня на фоне count. Это для вас одна маловажная циферка (вот реально ведь критично, 157832 лайков там или 157784?) а базе идти и вычитывать всю таблицу, проверять, видна ли каждая конкретная строка именно вашей текущей транзакции, группировать и считать. Да не будет это никогда нормально работать в OLTP нагрузке, конечно.
А задача простая и банальная. "как делать count в OLTP" описано много где - не делать count.
Как получить бесполезную циферку быстро - зависит от потребностей.
- спросить грубую оценку в explain и не считать вообще
- материализовать в отдельную таблицу post_id, likes_count, dislikes_count и обновлять триггерами
- материализовать в табличку и обновлять по таймеру, а сами счётчики считать где-то во внешнем мире - redis тот же хорошо умеет increment
- просто кэшировать и обновлять рейтинг в фоне (как самое простое для вашей view - заменить её на materialized view + периодический refresh concurrently и повесить индекс на рейтинг)
- ещё что угодно подходящее под вашу задачу и ваши ограничения, но по-прежнему исключающее count большого числа строк из oltp нагрузки