Я получаю плохую работу от DISTINCT. План объяснения показывает, что он выполняет SORT (GROUP BY), который звучит неправильно. Я ожидал бы, что какая-то агрегация HASH даст гораздо лучший результат. Есть ли намек на то, чтобы сказать оракулу использовать HASH для DISTINCT, а не сортировать? Я использовал/* + USE_HASH_AGGREGATION */в аналогичных ситуациях, но он не работает для DISTINCT.oracle different do sort
Так что это мой оригинальный запрос:
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
И это занимает 40 секунд. Теперь добавьте подсказку, чтобы сделать хэш вместо вида:
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| | | |
--------------------------------------------------------------------------------------------------------------------------------------------
+1: Хорошее место, хорошая работа и удача. Я тоже заинтригован этим. – MatBailie
Не могли бы вы показать планы объяснения/исполнения для каждого из запросов? Кроме того, следует отметить, что подсказка 'USE_HASH_AGGREGATION' официально недокументирована. –
Перекрестная рассылка с [dba.se]: http://dba.stackexchange.com/questions/13028 –