С SQL_CALC_FOUND_ROWS
запрос должен оценивать все, но не доставлять все строки. Избавление от этого должно быть полезным.
Чтобы фактически коснуться только 20 строк, нам нужно пройти через WHERE
, GROUP BY
и ORDER BY
с одним индексом. В противном случае нам, возможно, придется коснуться всех строк, отсортировать их и затем поставить 20. Очевидный индекс - (post_id)
; Я подозреваю, что это уже проиндексировано как PRIMARY KEY(post_id)
? (Будет полезно, если вы зададите SHOW CREATE TABLE
при задании вопросов.)
Другой способ выполнить объединение и получить желаемый результат, равный нулю, заключается в следующем. Обратите внимание, что это устраняет необходимость в GROUP BY
.
SELECT p.*,
IFNULL( ( SELECT SUM(v.visits)
FROM visits_day
WHERE post_id = p.post_id
),
0) AS visits
FROM posts AS p
ORDER BY post_id DESC
LIMIT 20 OFFSET 0
Если вы действительно нуждаетесь в подсчете, рассмотрите SELECT COUNT(*) FROM posts
.
ON v.post_id=p.post_id
в вашем запросе и WHERE post_id = p.post_id
просят INDEX(post_id)
на visits_day
. Это значительно ускорит оба варианта.