2个不同的小查询与1个子查询查询

时间:2013-04-09 10:19:26

标签: php mysql

我有这样的表

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

我需要获取每个名字,哪个personal_number在表格中重复超过1,结果必须是:

 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以字符串形式连接(像'222', '222'这样的东西)并运行其他查询

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

变体2比变体1快大约10倍,这对我来说很惊讶,我以为一个查询会更快,但是......

(表中有500 000行,列personal_number未编入索引)

那么,你对这样的案件意味着什么?为什么变体2比变体1快很多?

4 个答案:

答案 0 :(得分:5)

如本文http://www.mysqlperformanceblog.com/2010/10/25/mysql-limitations-part-3-subqueries所述,子查询似乎非常慢。

您应该尽量避免使用子查询并使用连接。

答案 1 :(得分: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";
  }
}

答案 2 :(得分: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会一次又一次地为每个记录重现内部表。

答案 3 :(得分:0)

由于索引没有完成所以1很慢,因为它必须匹配所选个人数字的个人数字。如果完成索引,则消耗的时间比以前少。 变体2是直接查询,因此它更快。