Да, вы можете переписать подзапросы как совокупные объединения (см. Ниже), но я почти уверен, что медлительность вызвана отсутствующими индексами , а не самим запросом.Используйте EXPLAIN
, чтобы увидеть, какие индексы можно добавить, чтобы ваш запрос выполнялся за доли секунды.
Для записи приведен эквивалент совокупного соединения.
SELECT `items_2`.*,
c.cnt AS `Comments`,
v.cnt AS `votes`,
`countrys`.`Name` AS `Country`
FROM `items` AS `items_2`
INNER JOIN `members` ON items_2.Member=members.Id AND members.Active = 1
INNER JOIN `members` AS `members_2` ON items_2.Member=members.Id
LEFT JOIN (
SELECT Script, COUNT(*) AS cnt
FROM `comments`
WHERE Active = 1
GROUP BY Script
) AS c
ON c.Script = items_2.Id
LEFT JOIN (
SELECT votes.Script, COUNT(*) AS cnt
FROM `votes`
WHERE Active = 1
GROUP BY Script
) AS v
ON v.Script = items_2.Id
LEFT JOIN `countrys` ON countrys.Id = members.Country
GROUP BY `items_2`.`Id`
ORDER BY `Created` DESC
LIMIT 10
Однако , поскольку вы используете LIMIT 10
, вы почти наверняка так же хорошо (или лучше) с подзапросами, которые у вас есть в настоящее время, чем с эквивалентом агрегированного соединения, который я предоставил выше дляссылка.
Это связано с тем, что плохой оптимизатор (и MySQL далеко не звездный) может в случае запроса агрегированного соединения выполнить агрегирование COUNT(*)
для полного содержимого Comments
и Votes
, прежде чем тратить впустую все, кроме 10 значений (ваш LIMIT
), тогда как в случае вашего исходного запроса он с самого начала будет смотреть только на строгий минимум до Comments
иЭто касается Votes
таблиц.
Точнее, использование подзапросов так, как это делает исходный запрос, обычно приводит к тому, что называется вложеннымPS с поиском индекса.Использование агрегатных объединений обычно приводит к слиянию или хеш-объединениям со сканированием индекса или просмотром таблицы.Первые (вложенные циклы) более эффективны, чем вторые (объединение слиянием и объединение хэшей), когда число циклов невелико (в вашем случае - 10). Однако вторые становятся более эффективными, когда первое приводит к слишком большому числу циклов (десятки / сотни тысяч и более), особенно в системах с медленными дисками, но большим объемом памяти.