Во-первых, у вас есть идентификатор выбора, который не существует, затем выполните левое соединение в поле from и, наконец, в сумме.Это попадает в вашу таблицу голосов 3 раза.ЕСЛИ каждый голос, возможно, связан с одним «ItemID», то лучше было бы предварительно агрегировать его как собственную «Sum», выполненную ОДИН РАЗ.
Кроме того, поскольку ваше последнее предложение «HAVING»прямое основание голосов, левая комбинация голосов становится мертвой точкой и, в конечном итоге, заканчивается обычным соединением.
С учетом вышесказанного, я бы предварительно запросил ПЕРВЫЕ голоса, которые ЗАВЕРШАЮТ с подходящим условием HAVING, затем присоединятся к элементам контента и другим объединениям ... Запрос к User_Foving - это подсчет ибудет либо 0 (не найден), либо 1 (найден).Не должно быть необходимости в случае / *
Мой первый псевдоним запроса "PQ" представляет "PreQuery"
SELECT
PQ.ItemID,
PQ.VSum as Votes,
PQ.HasVoted,
i.pending,
i.itemid,
i.message,
i.cid,
i.dateadded,
i.entrypoint,
i.userid,
c.name AS cname,
c.tag AS ctag,
( SELECT COUNT(commentid)
FROM `comments`
WHERE comments.itemid = PQ.itemid) AS commentcount,
( SELECT COUNT(*) FROM user_favorites uf
WHERE uf.itemid = PQ.itemid
AND uf.userid = @userid ) AS isFavorite
from
( SELECT
v.itemid,
SUM( case when v.Direction = 1 then 1
when v.Direction = 2 then -1
ELSE 0 end ) as VSum,
MAX( if( votes.userid = @userid, 1, 0 ) AS HasVoted
from
votes v
group by
v.itemid
having
VSum > -3 ) PQ
JOIN ContentItems i
ON PQ.ItemID = i.ItemID
and i.Pending = 0
JOIN Categories c
ON i.cid = c.cid
ORDER BY
i.dateadded DESC
Другие указали на необходимость индексов, согласились.Я хотел бы убедиться, что у каждой таблицы есть соответствующий индекс либо по идентификатору пользователя, либо по идентификатору предмета (или обоим, где это необходимо).
Пара других точек ... Вы изначально начинаете запрашивать все ContentItems, но оставляете присоединение к голосам... Но затем применяя элемент идентификатора пользователя.Это определенно пахнет запросом для конкретного пользователя.При этом я ДОБАВЬ ПРЕДВАРИТЕЛЬНО предварительно запустил весь запрос с выбором только ItemID, с которыми ID пользователя что-либо делал ... Затем продолжил запрос.