【问题标题】:Using SELECT within SELECT in mysql query在 mysql 查询中的 SELECT 中使用 SELECT
【发布时间】:2012-01-25 00:22:07
【问题描述】:

SELECT内使用SELECT是很常见的,以减少查询次数;但正如我所检查的那样,这会导致查询缓慢(这显然对 mysql 性能有害)。我有一个简单的查询

SELECT something
 FROM posts
 WHERE id IN (
  SELECT tag_map.id
  FROM tag_map
  INNER JOIN tags
  ON tags.tag_id=tag_map.tag_id
  WHERE tag IN ('tag1', 'tag2', 'tag3', 'tag4', 'tag5', 'tag6')
  )

这会导致“查询时间 3-4 秒;锁定时间大约 0.000090 秒;检查大约 200 行”的慢查询。

如果我拆分SELECT 查询,每个查询都会很快;但是这样会增加不擅长高并发的查询。

这是正常情况,还是我的编码有问题?

【问题讨论】:

  • SELECTSELECT 内?!这就像那部电影......选择。

标签: mysql sql database select


【解决方案1】:

在 MySQL 中,执行这样的子查询是“相关查询”。这意味着外部SELECT 的结果取决于内部SELECT 的结果。结果是您的内部查询每行执行一次,非常慢。

你应该重构这个查询;是加入两次还是使用两个查询大多无关紧要。加入两次会给你:

SELECT something
FROM posts
INNER JOIN tag_map ON tag_map.id = posts.id
INNER JOIN tags ON tags.tag_id = tag_map.tag_id
WHERE tags.tag IN ('tag1', ...)

有关更多信息,请参阅converting subqueries to JOINs 上的 MySQL 手册。

提示:EXPLAIN SELECT 将向您展示优化器计划如何处理您的查询。如果你看到 DEPENDENT SUBQUERY 你应该重构,这些速度非常慢。

【讨论】:

    【解决方案2】:

    您可以使用以下方法对其进行改进:

    SELECT something
    FROM posts
    INNER JOIN tag_map ON tag_map.id = posts.id
    INNER JOIN tags
    ON tags.tag_id=tag_map.tag_id
    WHERE <tablename>.tag IN ('tag1', 'tag2', 'tag3', 'tag4', 'tag5', 'tag6')
    

    只要确保你只选择你需要的,不要使用 *;还要说明您在哪个表中有标签列,以便您可以替换

    【讨论】:

    • 这就是我们所说的JOIN
    • 是的,内连接两次,至少我认为它比 in 子句快
    【解决方案3】:

    Join 过滤结果。第一次加入将保持满足第一个 ON 条件的结果,然后第二个条件在第二个 ON 条件下给出最终结果。

    SELECT something
    FROM posts
    INNER JOIN tag_map ON tag_map.id = posts.id
    INNER JOIN tags ON tags.tag_id = tag_map.tag_id AND tags.tag IN ('tag1', 'tag2', 'tag3', 'tag4', 'tag5', 'tag6');
    

    你可以看到这些关于堆栈溢出的讨论:

    question1 question2

    加入有助于降低时间复杂度并提高服务器的稳定性。

    将子查询转换为连接的信息:

    link1 link2 link3

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-16
      • 1970-01-01
      • 1970-01-01
      • 2013-07-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多