代码之家  ›  专栏  ›  技术社区  ›  Mathias Bynens

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

  •  1
  • Mathias Bynens  · 技术社区  · 14 年前

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

    目前有937条记录 和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 条款。我应该再加一点吗?

    另外,我知道我可以用PHP实现一个缓存系统,所以请不要告诉我:)我也很想知道如何改进这个查询。

    3 回复  |  直到 14 年前
        1
  •  1
  •   Mathias Bynens    14 年前

    用途:

       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
  •  1
  •   GrandmasterB    14 年前

    你想学习如何使用解释。这将执行sql语句,并显示正在使用哪些索引以及正在执行哪些行扫描。目标是减少行扫描的数量(即,数据库逐行搜索值)。

        3
  •  0
  •   Sjoerd    14 年前

    您可能需要一次一个子查询来查看哪个子查询最慢。

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