MySQL慢速SELECT查询

时间:2015-10-12 13:58:05

标签: mysql performance select indexing

我有一个查询,其中包含以下内容:

SELECT * FROM table1
WHERE confirmed = 0
AND resource = 123
AND id IN (
  SELECT id FROM table2 WHERE resource = 123
  AND added > 1440000000
)

运行需要将近3分钟,但我不知道为什么。这就是为什么我很困惑......

SELECT id FROM table2 WHERE resource = 123
AND added > 1440000000

此子查询没有结果。不是一个人。所以,我想如果我这样做了:

SELECT * FROM table1
WHERE confirmed = 0
AND resource = 123
AND id IN (
 0
)

运行应该需要大约相同的时间。除非它没有 - 它立即返回0结果如预期。这是怎么回事?将空查询结果与0进行比较有什么不同?

行号也很低。我已经运行了一个解释,它使用表1的确认密钥和表2中的主键。行数分别为5500/20000。

非常感谢任何想法!谢谢!

2 个答案:

答案 0 :(得分:1)

使用显式join可以更快地运行查询。如果子查询未返回重复值:

SELECT t1.*
FROM table1 t1 JOIN
     (SELECT id FROM table2 WHERE resource = 123 AND added > 1440000000
     ) t2
     ON t1.id = t2.id
WHERE confirmed = 0 AND resource = 123;

此外,MySQL通常更好地优化NOT EXISTS

SELECT t1.*
FROM table1 t1
WHERE confirmed = 0 AND resource = 123 AND
      NOT EXISTS (SELECT 1
                  FROM table2 t2
                  WHERE t2.id = t1.id AND t2.resource = 123 AND t2.added > 1440000000
                 );

此查询将以table2(id, resource, added)上的索引运行得更快。

答案 1 :(得分:1)

IN ( SELECT ... )在5.6之前优化得很差。 5.6更好,但仍然不是很好。

必须首先计算

JOIN ( SELECT ... ),并且需要临时表。所以它不如下面的普通JOIN那么好。

SELECT  *
    FROM  table1 AS t1
    JOIN  table2 AS t2 ON t2.id = t1.id
    WHERE  t1.confirmed = 0
      AND  t1.resource = 123
      AND  t2.resource = 123
      AND  t2.added > 1440000000 

并且

table2:  INDEX(resource, added)
table1:  INDEX(resource, confirmed)