2个不同的小查询vs 1个带子查询的查询


2 different small query vs 1 query with subquery

我有一个这样的表

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倍,这对我来说是惊喜,我认为一个查询会更快,但是…

(在表是500000行,列personal_number未索引)

那么,像这样的情况你是什么意思?为什么变体2比变体1快得多?

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

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

第一个查询有重子查询。你必须避免这种情况。您的问题的最佳解决方案只有一个查询:

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

此查询将只返回每个重复的名称一次。如果您想要显示重复名称的次数,则必须使用next查询:

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";
  }
}

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

这样会更快:

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

编辑:如果这比变体1快,那么这意味着在变体1 mysql为每条记录一次又一次地复制内部表。