MySQL慢速选择查询
我有一个问题,大致如下:MySQL慢速选择查询,mysql,performance,select,indexing,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 > 14
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进行比较有什么不同
行数也很低。我已经运行了一个explain,它使用表1的确认键和表2中的主键。行数分别为5500/20000
如果您有任何想法,我们将不胜感激!谢谢大家! 使用显式的
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通常更好地优化不存在的:
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
);
如果表2(id,资源,已添加)中的索引在5.6版之前(选择…
中的优化非常差,则此查询将运行得更快。5.6更好,但仍然不太好
JOIN(SELECT…
必须首先计算,并且需要一个临时表。所以它不如下面的普通连接好
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)
因为对于语句中执行的每一行选择。在这里使用JOIN
不是更合适吗?如果我错过了smth,请纠正我。如果您已经运行了“解释”,那么将其包括在内可能是一个好主意。您确定资源和添加的字段在您的数据库中被索引了吗?Paul,我认为您是对的-虽然它是0个结果,但可能需要一些时间来为每一行运行每个子查询。我以为乐观主义者会做一次子查询,将其保存在内存中,然后每次比较结果,但结果并非如此。听起来对吗?谢谢Jacub和ITOctopus的建议。我已经为这个问题更改了字段名等,所以我认为只解释“解释”比全部更改更容易。资源上有索引,并按建议添加了字段。:)谢谢戈登,这很有用。我猜想,尽管子查询没有返回任何结果,但它仍然需要相当长的时间才能运行。我将更改我的查询,希望这样做。更多讨论:。