2013-04-09 64 views
13

我有台这样的2个不同的小的查询VS 1项的查询与子查询

name  | personal_number 
----------------------------------------- 
Jon  | 222 
Alex  | 555 
Jon  | 222 
Jimmy  | 999 

我需要让每一个名字,这personal_number表超过1 repeates,那就是结果一定是:

Jon   
Jon   

所以,变体1):

SELECT name FROM mytable WHERE personal_number IN (
     SELECT personal_number FROM mytable GROUP BY personal_number 
     HAVING COUNT(*) > 1 
) 

变体2):

SELECT personal_number FROM mytable GROUP BY personal_number 
     HAVING COUNT(*) > 1 
) 

然后,使用PHP,检索personal_numbers加入为字符串(soemthing这样'222', '222'),并运行其他查询

SELECT name FROM mytable WHERE personal_number IN(here joined string) 

变2项工程大约快10倍,比变种1,这是惊喜对我来说,我在想,一个查询会更快,但是......

(在表500个000行,列personal_number没有索引)

所以,你的意思是这样的情况吗?为什么变体2比变体1快多了?

+2

+1的好问题并且在运行一些基准测试之前不要求。 – enenen 2013-04-09 10:22:42

+2

解释这两个查询应该显示它 – 2013-04-09 10:34:59

+0

如果名称和个人编号相互依赖,则应该将您的表格移至第二个标准格式 – Argeman 2013-04-09 10:40:51

回答

0

这应该是更快:

SELECT name FROM mytable join (
     SELECT personal_number FROM mytable GROUP BY personal_number 
     HAVING COUNT(*) > 1 
)a using (personel_number) 

编辑:如果这是比变体1快,那么就意味着在变体1个MySQL的一次又一次再现每个记录的内部表。

+2

这不能解释性能差异。 – Bart 2013-04-09 10:29:49

+0

@禁止,它不。 – palindrom 2013-04-09 10:30:38

0

由于索引编制没有完成,因此1很慢,因为它必须匹配来自所选个人编号的个人编号。如果建立索引,它会比以前消耗更少的时间。 变体2是一个直接查询,因此它的速度更快。

1

第一个查询具有沉重的子查询。你必须避免这一点。 有关问题的最佳解决方案是只有一个查询:

SELECT name FROM mytable GROUP BY personal_number HAVING COUNT(*) > 1; 

这个查询将返回你每次重复的名字只有一次。如果你想显示重复多次的名字,因为他们遇到了你必须使用一个查询:

SELECT name, COUNT(*) AS count FROM mytable GROUP BY personal_number HAVING COUNT(*) > 1; 

然后在PHP做这样的事情:

foreach ($rows as $row) { 
    for ($i = 0; $i++; $i < $row['count']) { 
    echo $row['name'] . "\n"; 
    } 
}