简单的MySQL查询花费很长时间来计算

时间:2011-11-15 04:36:52

标签: mysql phpmyadmin xampp

我只是在学习MySQL而且我遇到了问题。

有时,对于各种查询,MySQL开始以100%的CPU使用率计算15-20秒而不是通常会返回结果:

  

查询花了0.1780秒。

它发生在非常简单的查询上。例如,此查询花了0.36秒。

(SELECT DISTINCT a1.actor 
 FROM   actors AS a1, 
        actors AS a2 
 WHERE  a1.title = a2.title 
        AND a1.YEAR = a2.YEAR 
        AND a1.actor = a2.actor 
        AND a1.character_name <> a2.character_name) 

表格列表(7000行)耗时0.001秒。

另一方面,当我只想将这两者结合起来时,MySQL会疯狂并开始计算30秒然后最终返回:Query took 0.1800 sec)

SELECT actor 
FROM   actors 
WHERE  actor NOT IN (SELECT DISTINCT a1.actor 
                     FROM   actors AS a1, 
                            actors AS a2 
                     WHERE  a1.title = a2.title 
                            AND a1.YEAR = a2.YEAR 
                            AND a1.actor = a2.actor 
                            AND a1.character_name <> a2.character_name) 

为什么会这样?

这是另一个例子。此查询大约需要2秒钟并报告0.5

SELECT DISTINCT a1.character_name 
FROM   (actors AS a1 
        NATURAL JOIN movies AS m1), 
       (actors AS a2 
        NATURAL JOIN movies AS m2) 
WHERE  a1.character_name = a2.character_name 
       AND ( m1.title <> m2.title 
              OR ( m1.title = m2.title 
                   AND m1.year <> m2.year ) ) 
       AND m1.country <> m2.country 

另一方面,此查询需要15-20秒,CPU 100%,但报告0.3秒。 (唯一的区别是AND(....)之后的括号

SELECT DISTINCT a1.character_name 
FROM   (actors AS a1 
        NATURAL JOIN movies AS m1), 
       (actors AS a2 
        NATURAL JOIN movies AS m2) 
WHERE  a1.character_name = a2.character_name 
       AND m1.title <> m2.title 
        OR ( m1.title = m2.title 
             AND m1.YEAR <> m2.YEAR ) 
           AND m1.country <> m2.country 

我正在使用phpMyAdmin和最新的XAMPP进行测试。

更新

错误的查询时间似乎与phpMyAdmin有关,在命令行上我得到以下时间:

  • 第一个查询:MySQL: 0.36 s - PostgreSQL: 0.37 s
  • 第二个查询:MySQL: 43 s - PostgreSQL: 0.42 s
  • 第三次查询:MySQL: 4.86 s - PostgreSQL: 0.05 s
  • 第4次查询:MySQL: 1分5秒 - PostgreSQL: 15秒

所以我得到了为什么错误地报告查询时间(phpMyAdmin或XAMPP中的错误)的答案,我对为什么这些类似的查询在运行时间上有如此大的差异感兴趣?

更新2:

为了完整起见,我也使用PostgreSQL进行了测试

4 个答案:

答案 0 :(得分:4)

您是否尝试使用mysql cmd提示测试您的查询?如果问题仍然存在,那么问题可能是mysql,但如果问题解决了,那么我认为你有phpmyadmin的问题。因此,请在使用mysql cmd提示尝试查询后,是否仍然存在问题。

答案 1 :(得分:1)

更改此项(您的第一个查询)

SELECT DISTINCT a1.actor 
FROM   actors AS a1, 
actors AS a2 
WHERE  a1.title = a2.title 
AND a1.YEAR = a2.YEAR 
AND a1.actor = a2.actor 
AND a1.character_name <> a2.character_name) 

到此:

SELECT *
FROM actors a1
JOIN actors a2 ON (a1.title = a2.title AND a1.actor = a2.actor)
GROUP BY a1.actor
HAVING a1.character_name <> a2.character_name

并为其他人使用相同的样式,同时确保表上有适当的索引。

答案 2 :(得分:1)

SELECT actor 
FROM   actors 
WHERE  actor NOT IN (SELECT DISTINCT a1.actor 
                     FROM   actors AS a1, 
                            actors AS a2 
                     WHERE  a1.title = a2.title 
                            AND a1.YEAR = a2.YEAR 
                            AND a1.actor = a2.actor 
                            AND a1.character_name <> a2.character_name)

上述查询看起来似乎正在尝试选择从未在单个标题上播放过多个角色的演员。你可以说:

select   actor
from     actors
group by actor, year, title
having   count(character_name) = 1

但是,我知道你的问题不是关于你的sql写作能力而你只是想弄清楚为什么MySql的奇怪行为。我的猜测是它从执行时间中排除了某些东西。例如,谷歌表示花了0.09秒才能得到你的结果,但你知道你等了10秒才能加载页面。谷歌没有考虑从服务器到你的计算机所花费的9.91秒...他们需要多长时间才能查询数据。

这绝对看起来像MySql应该解决的一个明显的问题,因为与Google无法知道等式的其他部分不同,MySql应该能够将整个过程合并到时间计算中。

答案 3 :(得分:0)

尝试使用EXPLAIN来分析您的查询。我建议 - 不要使用子查询。