Как оптимизировать этот низкопроизводительный запрос MySQL?
В настоящее время я использую следующий запрос для jsPerf. В вероятном случае вы не знаете jsPerf - есть две таблицы: pages
содержащие контрольные примеры / ревизии, и tests
содержащий фрагменты кода для тестов внутри тестовых случаев.
В настоящее время 937 записей pages
и 3817 записей в tests
,
Как видите, загрузка страницы "Browse jsPerf", где используется этот запрос, занимает довольно много времени.
Выполнение запроса занимает около 7 секунд:
SELECT
id AS pID,
slug AS url,
revision,
title,
published,
updated,
(
SELECT COUNT(*)
FROM pages
WHERE slug = url
AND visible = "y"
) AS revisionCount,
(
SELECT COUNT(*)
FROM tests
WHERE pageID = pID
) AS testCount
FROM pages
WHERE updated IN (
SELECT MAX(updated)
FROM pages
WHERE visible = "y"
GROUP BY slug
)
AND visible = "y"
ORDER BY updated DESC
Я добавил индексы на все поля, которые появляются в WHERE
статьи. Должен ли я добавить больше?
Как можно оптимизировать этот запрос?
PS Я знаю, что мог бы внедрить систему кэширования в PHP - возможно, так и будет, поэтому, пожалуйста, не говорите мне:) Я просто очень хотел бы узнать, как можно улучшить этот запрос.
3 ответа
Использование:
SELECT x.id AS pID,
x.slug AS url,
x.revision,
x.title,
x.published,
x.updated,
y.revisionCount,
COALESCE(z.testCount, 0) AS testCount
FROM pages x
JOIN (SELECT p.slug,
MAX(p.updated) AS max_updated,
COUNT(*) AS revisionCount
FROM pages p
WHERE p.visible = 'y'
GROUP BY p.slug) y ON y.slug = x.slug
AND y.max_updated = x.updated
LEFT JOIN (SELECT t.pageid,
COUNT(*) AS testCount
FROM tests t
GROUP BY t.pageid) z ON z.pageid = x.id
ORDER BY updated DESC
Вы хотите узнать, как использовать EXPLAIN. Это выполнит оператор sql и покажет вам, какие индексы используются и какие проверки строк выполняются. The goal is to reduce the number of row scans (ie, the database searching row by row for values).
Возможно, вы захотите попробовать подзапросы по одному, чтобы увидеть, какой из них самый медленный.
Этот запрос:
SELECT MAX(updated)
FROM pages
WHERE visible = "y"
GROUP BY slug
Делает это сортирует результат по слизнякам. Это, вероятно, медленно.