如何优化这种低性能的MySQL查询?

时间:2010-08-25 17:50:00

标签: sql mysql performance subquery jsperf

我目前正在使用jsPerf的以下查询。在可能的情况下,您不知道jsPerf - 有两个表:pages包含测试用例/修订版,tests包含测试用例内测试的代码片段。

pages目前有937条记录,tests有3817条记录。

正如您所看到的,加载the “Browse jsPerf” page需要花费很长时间才能使用此查询。

查询大约需要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子句中显示的所有字段上添加了索引。我应该添加更多吗?

如何优化此查询?

P.S。我知道我可以在PHP中实现一个缓存系统 - 我可能会这样做,所以请不要告诉我:)我真的很想知道如何改进这个查询。

3 个答案:

答案 0 :(得分:1)

您想了解如何使用EXPLAIN。这将执行sql语句,并显示正在使用的索引以及正在执行的行扫描。目标是减少行扫描的次数(即,数据库逐行搜索值)。

答案 1 :(得分:1)

使用:

   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

答案 2 :(得分:0)

您可能希望一次尝试一个子查询,以查看哪一个最慢。

此查询:

SELECT MAX(updated)
  FROM pages
  WHERE visible = "y"
  GROUP BY slug

使用slug对结果进行排序。这可能很慢。