Хороший способ ускорить этот запрос - это реорганизовать его для выполнения отложенного соединения . Цель состоит в том, чтобы выполнить операцию SELECT ... ORDER BY ... LIMIT...
для набора результатов с наименьшим возможным числом столбцов. Почему это важно? Заказ больших наборов результатов обходится дороже, чем заказ маленьких, особенно когда LIMIT
отбрасывает большинство результатов заказа.
Итак, начнем с этого подзапроса:
SELECT p.id, c.id
FROM posts p
JOIN cadastro c ON p.user=c.id
WHERE p.user=? and p.delete='0'
ORDER BY p.id
LIMIT ?
Там у вас есть соответствующие значения posts.id и cadastro.id для вашего запроса. Вы можете ускорить это с помощью составного индекса покрытия для posts(user, delete)
: планировщик запросов может полностью удовлетворить этот подзапрос путем сканирования части этого составного индекса.
Затем вы присоединяете это к версии вашего основного запроса.
SELECT c.nome, p.foto, c.user, p.user, p.id, p.data, p.titulo,
p.youtube, pp.foto,
count(DISTINCT likes.user) as likes_count,
count(distinct comentarios.id) as comentarios_count,
count(DISTINCT l2.user) as count2
FROM (
SELECT p.id pid, c.id cid
FROM posts p
JOIN cadastro c ON p.user=c.id
WHERE p.user=? and p.delete='0'
ORDER BY p.id, c.id
LIMIT ?
) selector
JOIN posts p ON selector.pid = p.id
JOIN cadastro c ON selector.cid = p.user
left join profile_picture pp on p.user = pp.user
left join likes on likes.post = p.id
left join comentarios on comentarios.foto = p.id and comentarios.delete = 0
left join likes l2 on l2.post = p.id and l2.user = ?
where p.user=? and p.delete='0'
group by p.id
order by p.id limit ?
Вам необходимо повторить операцию ORDER BY ... LIMIT ?
, поскольку ваши левые объединения могут увеличить размер конечного набора результатов, а вам нужно ограничить его.
Трудно сказать, какие индексы будут ускорять оставшуюся часть запроса без дополнительной информации о ваших таблицах. Все эти операции COUNT (DISTINCT ...) неизбежно несколько дорогостоящи. Вы можете прочитать это: https://use -the-index-luke.com /
Pro tip Вы используете и, возможно, неправильно используете печально известное расширение для GROUP BY
в MySQL . Ваш GROUP BY
должен сказать это, или значения c.nome
и c.user
могут быть выбраны непредсказуемым образом.
GROUP BY p.id, c.id
Pro tip Индексы с одним столбцом обычно мало помогают запросам или подзапросам: MySQL может использовать только один индекс на таблицу в запросе. Таким образом, покрытие индексов столбцами в правильном порядке может сильно помочь. Не надо просто добавлять кучу индексов в надежде ускорить запросы.