【问题标题】:Why is my SELECT with a subquery and JOINs so slow?为什么我的带有子查询和 JOIN 的 SELECT 这么慢?
【发布时间】:2012-08-13 20:43:37
【问题描述】:

此查询需要 10 秒才能完成。但是当我手动执行子查询并将t1.id 限制更改为该列表时,它会在 0.00 秒内完成。如何让 MySQL 更快地执行查询?

SELECT t1.col1, t2.col2, t3.col3
FROM t1, t2, t3
WHERE  t1.t2id = t2.id AND t1.t3id = t3.id
AND t1.id IN ( SELECT id FROM t4 WHERE blah = 123 )

另外,为什么会这样?我想 MySQL 在过滤 t1.id 之前以某种方式连接了所有三个表。

t1、t2 和 t3 分别包含 3000、15 和 80 行。子查询返回 2-10 行。

【问题讨论】:

  • 尝试explain select ...并使用像inner join ...这样的显式连接
  • @juergend 从评论分数来看你似乎是对的,但使用明确的INNER JOIN 加入 t2 和 t3 似乎没有任何改变。
  • 使用explain 查看查询的执行计划。然后你可以看到它在哪里消耗了那么多时间。
  • 用 INNER JOIN 连接 t1 和 t2,或 t1 和 t3 不会有任何改变。 FROM t1, t2, t3 与使用 INNER JOIN 相同。
  • @juergend 抱歉,我对此不是很有经验。我可以看到两个部分包含数千行,并且它们在没有键的情况下“使用 where”。我还是不明白为什么会这样。

标签: mysql performance join subquery innodb


【解决方案1】:

重写不带子查询的查询:

SELECT t1.col1, t2.col2, t3.col3
FROM t1, t2, t3, (SELECT id FROM t4 WHERE blah = 123) AS t4
WHERE  t1.t2id = t2.id AND t1.t3id = t3.id
AND t1.id=t4.id

确保您对WHERE 子句中使用的字段有索引。

【讨论】:

    【解决方案2】:

    尝试使用“INNER JOIN”而不是“IN”功能。 这样你的 sql 指令会更有执行力。

    SELECT t1.col1, t2.col2, t3.col3
    FROM ((t1 INNER JOIN t2 ON t1.t2id = t2.id) INNER JOIN t3 ON t1.t3id = t3.id) INNER JOIN t4 ON t1.id = t4.id
    WHERE t4.blah = 123
    

    【讨论】:

      【解决方案3】:

      如果您在语句上运行 EXPLAIN,您可能会看到 MySql 在磁盘上创建了一个临时表:如果内联选择(您的 IN 术语)中的数据足够大,通常会发生这种情况。

      简而言之:

      a) 使用EXPLAIN 来查看数据库中发生了什么(并查看此行为如何随着数据的增加而变化)

      b) 尽可能避免内联子查询

      c) 请记住,MySql 只有一个嵌套循环连接算法可供使用(其他数据库也使用哈希连接和合并连接算法),因此您可能会看到较小数据集的“更少”解析正在进行,但突然到达临界点时下车。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多