14

我有这样的桌子

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

4 回答 4

5

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

您应该尽量避免使用子查询并改用加入。

于 2013-04-09T10:35:26.223 回答
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";
  }
}
于 2013-04-09T10:37:41.803 回答
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 一次又一次地为每个记录再现内部表。

于 2013-04-09T10:29:12.323 回答
0

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

于 2013-04-09T10:30:48.137 回答