oracle明确做排序

时间:2012-02-14 16:30:22

标签: sql oracle

我的DISTINCT表现不佳。解释计划表明它正在进行SORT(GROUP BY),听起来不对。我希望某种HASH聚合能产生更好的结果。是否有提示告诉oracle使用HASH进行DISTINCT而不是排序? 我在类似情况下使用了/ * + USE_HASH_AGGREGATION * /,但它不适用于DISTINCT。

所以这是我原来的疑问:

SELECT
count(distinct userid) n, col
FROM users
GROUP BY col;

用户有30M行,每个用户ID有12次。此查询需要70秒。

现在我们将其重写为

SELECT
count(userid) n, col
FROM
(SELECT distinct userid, col FROM users)
GROUP BY col

需要40秒。 现在添加提示来执行hash而不是sort:

SELECT
count(userid) n, col
FROM
(SELECT /*+ USE_HASH_AGGREGATION */ distinct userid, col FROM users)
GROUP BY col

需要10秒钟。

如果有人可以向我解释为什么会发生这种情况,或者我如何能够将第一个简单的查询打造成与第3个一样好的工作,那就太棒了。
我关心查询简单性的原因是因为实际生成了这些查询。

计划: 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|   |   |      |
--------------------------------------------------------------------------------------------------------------------------------------------

1 个答案:

答案 0 :(得分:2)

如何尝试以下方法: 如果您在col和userid上有索引,它应该在索引中完全解析,而不需要触摸该表。

Select count(userid) n, col
from (select col, userid from users group by col, userid)
group by col
;