我正在HSQLDB
服务器上执行一些测试,其中包含一个包含500 000个条目的表。该表没有索引。有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
修改:
我做了额外的测试。 HSQLDB
中包含所有不同业务键的500 000条记录,DISTINCT
的效果现在更好 - 3秒,而GROUP BY
大约需要9秒。
在MySQL
中,两个查询都预先形成相同的内容:
MySQL:500 000行 - 5 000个不同的业务键:
两个查询:0.5秒
MySQL:500 000行 - 所有不同的业务键:
SELECT DISTINCT ...
- 11秒
SELECT ... GROUP BY business_key
- 13秒
所以问题只与HSQLDB
有关。
如果有人能解释为什么会有这么大的差异,我将非常感激。
答案 0 :(得分:66)
这两个问题表达了同样的问题。显然,查询优化器选择两个不同的执行计划。我的猜测是distinct
方法执行如下:
business_key
值复制到临时表 group by
可以执行如下:
business key
的每个值存储在哈希表中第一种方法优化内存使用:当必须换出部分临时表时,它仍然可以很好地执行。第二种方法优化了速度,但如果存在许多不同的密钥,则可能需要大量内存。
由于你有足够的内存或几个不同的键,第二种方法优于第一种方法。在两个执行计划之间看到10倍甚至100倍的性能差异并不罕见。