我在DISTINCT中表现不佳.解释计划表明它正在进行听起来不正确的SORT(GROUP BY).我希望某种HASH聚合产生更好的结果.有没有提示告诉oracle使用HASH进行DISTINCT而不是排序?
在类似的情况下,我使用过/ * USE_HASH_AGGREGATION * /,但是它不能用于DISTINCT.
在类似的情况下,我使用过/ * USE_HASH_AGGREGATION * /,但是它不能用于DISTINCT.
所以这是我原来的查询:
SELECT count(distinct userid) n,col FROM users GROUP BY col;
用户拥有30M行,每个用户标识都有12次.此查询需要70秒.
现在我们把它重写为
SELECT count(userid) n,col FROM (SELECT distinct userid,col FROM users) GROUP BY col
SELECT count(userid) n,col FROM (SELECT /*+ USE_HASH_AGGREGATION */ distinct userid,col FROM users) GROUP BY col
需要10秒钟.
如果有人可以向我解释为什么会发生这种情况,或者我如何能够将第一个简单的查询打到第三个工作,那将是太棒了.
我关心查询简单性的原因是因为这些查询实际上是生成的.
计划:
1)慢:
---------------------------------------------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads | OMem | 1Mem | Used-Mem | Used-Tmp| -------------------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | 5 |00:01:12.01 | 283K| 292K| | | | | | 1 | SORT GROUP BY | | 1 | 5 | 5 |00:01:12.01 | 283K| 292K| 194M| 448K| 172M (0)| 73728 | | 2 | TABLE ACCESS FULL| USERS | 1 | 29M| 29M|00:00:08.17 | 283K| 283K| | | | |
2)快
-------------------------------------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads | OMem | 1Mem | Used-Mem | -------------------------------------------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | 5 |00:00:13.09 | 283K| 283K| | | | | 1 | SORT GROUP BY | | 1 | 5 | 5 |00:00:13.09 | 283K| 283K| 3072 | 3072 | 2048 (0)| | 2 | VIEW | | 1 | 8647K| 2445K|00:00:13.16 | 283K| 283K| | | | | 3 | HASH UNIQUE | | 1 | 8647K| 2445K|00:00:12.57 | 283K| 283K| 113M| 10M| 216M (0)| | 4 | TABLE ACCESS FULL| USERS | 1 | 29M| 29M|00:00:07.68 | 283K| 283K| | | | --------------------------------------------------------------------------------------------------------------------------------------------
解决方法
尝试以下操作如何:
如果您在col和userid上有一个索引,它应该在索引中完全解析,而不需要触摸表.
如果您在col和userid上有一个索引,它应该在索引中完全解析,而不需要触摸表.
Select count(userid) n,col from (select col,userid from users group by col,userid) group by col ;