使用group vs vs distinct的巨大性能差异

我正在一个包含500 000条目的表在HSQLDB服务器上执行一些testing。 该表没有索引。 有5000个不同的业务密钥。 我需要一个列表。 当然,我从一个DISTINCT查询开始:

 SELECT DISTINCT business_key FROM memory WHERE concept <> 'case' or attrib <> 'status' or value <> 'closed' 

大约需要90秒!

然后我尝试使用GROUP BY

 SELECT business_key FROM memory WHERE concept <> 'case' or attrib <> 'status' or value <> 'closed' GROUP BY business_key 

这需要1秒钟!

试图找出差异我跑EXLAIN PLAN FOR但它似乎给这两个查询相同的信息。

EXLAIN PLAN FOR DISTINCT ...

 isAggregated=[false] columns=[ COLUMN: PUBLIC.MEMORY.BUSINESS_KEY ] [range variable 1 join type=INNER table=MEMORY alias=M access=FULL SCAN condition = [ index=SYS_IDX_SYS_PK_10057_10058 other condition=[ OR arg_left=[ OR arg_left=[ NOT_EQUAL arg_left=[ COLUMN: PUBLIC.MEMORY.CONCEPT] arg_right=[ VALUE = case, TYPE = CHARACTER]] arg_right=[ NOT_EQUAL arg_left=[ COLUMN: PUBLIC.MEMORY.ATTRIB] arg_right=[ VALUE = status, TYPE = CHARACTER]]] arg_right=[ NOT_EQUAL arg_left=[ COLUMN: PUBLIC.MEMORY.VALUE] arg_right=[ VALUE = closed, TYPE = CHARACTER]]] ] ]] PARAMETERS=[] SUBQUERIES[] Object References PUBLIC.MEMORY PUBLIC.MEMORY.CONCEPT PUBLIC.MEMORY.ATTRIB PUBLIC.MEMORY.VALUE PUBLIC.MEMORY.BUSINESS_KEY Read Locks PUBLIC.MEMORY WriteLocks 

EXLAIN PLAN FOR SELECT ... GROUP BY ...

 isDistinctSelect=[false] isGrouped=[true] isAggregated=[false] columns=[ COLUMN: PUBLIC.MEMORY.BUSINESS_KEY ] [range variable 1 join type=INNER table=MEMORY alias=M access=FULL SCAN condition = [ index=SYS_IDX_SYS_PK_10057_10058 other condition=[ OR arg_left=[ OR arg_left=[ NOT_EQUAL arg_left=[ COLUMN: PUBLIC.MEMORY.CONCEPT] arg_right=[ VALUE = case, TYPE = CHARACTER]] arg_right=[ NOT_EQUAL arg_left=[ COLUMN: PUBLIC.MEMORY.ATTRIB] arg_right=[ VALUE = status, TYPE = CHARACTER]]] arg_right=[ NOT_EQUAL arg_left=[ COLUMN: PUBLIC.MEMORY.VALUE] arg_right=[ VALUE = closed, TYPE = CHARACTER]]] ] ]] groupColumns=[ COLUMN: PUBLIC.MEMORY.BUSINESS_KEY] PARAMETERS=[] SUBQUERIES[] Object References PUBLIC.MEMORY PUBLIC.MEMORY.CONCEPT PUBLIC.MEMORY.ATTRIB PUBLIC.MEMORY.VALUE PUBLIC.MEMORY.BUSINESS_KEY Read Locks PUBLIC.MEMORY WriteLocks 

编辑 :我做了额外的testing。 在HSQLDB有500 000个logging,所有不同的业务密钥, DISTINCT的性能现在更好 – 3秒,而GROUP BY耗时约9秒。

MySQL两个查询都是相同的:

MySQL:500 000行 – 5000个不同的业务密钥:两个查询:0.5秒MySQL:500 000行 – 所有不同的业务密钥: SELECT DISTINCT ... – 11秒SELECT ... GROUP BY business_key – 13秒

所以这个问题只和HSQLDB有关。

如果有人能解释为什么会有这么大的差异,我将不胜感激。

这两个查询expression了同样的问题。 查询优化器显然select了两个不同的执行计划。 我的猜测是, distinct方法是执行如下:

  • 将所有business_key值复制到临时表
  • sorting临时表
  • 扫描临时表,返回每个不同于之前的项目

group by可以被执行,如:

  • 扫描整个表,将每个business key值存储在散列表中
  • 返回哈希表的键

第一种方法优化了内存使用情况:当临时表的一部分必须被交换出来时,仍然能够很好地执行。 第二种方法优化速度,但如果有很多不同的密钥,可能需要大量的内存。

既然你有足够的内存或几个不同的键,第二种方法胜过第一种。 在两个执行计划之间看到10倍甚至100倍的性能差异并不罕见。