Как оптимизировать этот низкопроизводительный запрос 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

Делает это сортирует результат по слизнякам. Это, вероятно, медленно.

Другие вопросы по тегам