为什么在这个MySQL实例中,GROUPBY比同一个表连接慢?

为什么在这个MySQL实例中,GROUPBY比同一个表连接慢?,mysql,Mysql,作为一个团队,我们习惯使用MS SQL Server。这是我们第一次使用MySQL,我们对一个特殊的行为感到惊讶 我们有以下表格: CREATE TABLE `People` ( `PersonId` int(11) NOT NULL AUTO_INCREMENT, `AddressKey` varchar(255) DEFAULT NULL, `NameKey` varchar(255) DEFAULT NULL, PRIMARY KEY (`PersonId`), KEY

作为一个团队,我们习惯使用MS SQL Server。这是我们第一次使用MySQL,我们对一个特殊的行为感到惊讶

我们有以下表格:

CREATE TABLE `People` (
  `PersonId` int(11) NOT NULL AUTO_INCREMENT,
  `AddressKey` varchar(255) DEFAULT NULL,
  `NameKey` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`PersonId`),
  KEY `AddressKey` (`AddressKey`),
  KEY `NameKey` (`NameKey`)
) ENGINE=InnoDB AUTO_INCREMENT=243771506 DEFAULT CHARSET=utf8;
它非常大,有几亿张唱片。我们发现里面有一些重复的

为了识别它们,我们首先构建一个标准的GROUPBY语句

select NameKey, AddressKey, count(*) as dupes from People
group by NameKey, AddressKey having dupes > 1
limit 2;
在此查询上使用EXPLAIN可生成:

id  select_type table           partitions  type    possible_keys       key     key_len ref                     rows        filtered    Extra
1   SIMPLE      s1                          ALL     AddressKey,NameKey                                          215543661   100.00      Using where
1   SIMPLE      s2                          ref     AddressKey,NameKey  NameKey 768     s1.NameKey              5           0.92        Using index condition; Using where
然而,这被证明是可笑的缓慢。进行自联接要快得多:

select s1.* from People s1 join People s2 
on s1.NameKey = s2.NameKey and s1.AddressKey = s2.AddressKey
 where s1.SuppressionId <> s2.SuppressionId
limit 50;

根据SQLServer扫描表的方式,我们假设GROUPBY会快得多,但事实并非如此。为什么不呢?我们可以做些什么来提高这个查询的性能吗?

可能是因为它实际上必须具体化可能包含任意行数的整个组。它没有短路的方法。
按名称键分组,地址键
需要
索引(名称键,地址键)
那么查询会更快。。。。您将使用
EXPLAIN[query]
获得更多信息。您还应该为这两个查询包含这些信息。表上有索引吗?没有,您需要创建一个包含两列的索引
create index idx_somename on People(AddressKey,NameKey)
取决于GROUP BY查询是否需要使用临时表和快速排序,在EXPLAIN output@JorgeCampos的额外列中是否“使用临时;使用文件排序”,这些才是真正的MySQL性能杀手。如果MySQL无法在内存中保存临时表,它将创建一个基于MyISAM磁盘的临时表。。因此,您正在使用随机磁盘i/o对磁盘进行快速排序(因为GROUP BY具有自动排序方式)。。如果索引正确,您将不会遇到此问题,MySQL将像高速列车一样运行。。
id  select_type table           partitions  type    possible_keys   key key_len ref rows        filtered    Extra
1   SIMPLE      People                      ALL                                     215543970   100.00      Using temporary; Using filesort