我有这样的表
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快很多?
答案 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是直接查询,因此它更快。