Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL慢速选择查询_Mysql_Performance_Select_Indexing - Fatal编程技术网

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的建议。我已经为这个问题更改了字段名等,所以我认为只解释“解释”比全部更改更容易。资源上有索引,并按建议添加了字段。:)谢谢戈登,这很有用。我猜想,尽管子查询没有返回任何结果,但它仍然需要相当长的时间才能运行。我将更改我的查询,希望这样做。更多讨论:。