Как оптимизировать этот низкопроизводительный запрос MySQL?
-
01-10-2019 - |
Вопрос
В настоящее время я использую следующий запрос для 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 - я, наверное, будет, поэтому, пожалуйста, не скажите мне :) Мне просто нравится узнать, как этот запрос может быть улучшен.
Решение
Использовать:
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
Другие советы
Вы хотите узнать, как использовать объяснение. Это выполнит оператор SQL и показывает, какие индексы используются, и какие сканы строки выполняются. Цель состоит в том, чтобы уменьшить количество сканов строк (т. Е. База данных поиска строки по строке для значений).
Возможно, вы захотите попробовать подзапросы по одному, чтобы увидеть, какой из них медленнее.
Этот запрос:
SELECT MAX(updated)
FROM pages
WHERE visible = "y"
GROUP BY slug
Делает его сортировкой результатом слизняка. Это, вероятно, медленно.