2012-02-14 21 views
10

DISTINCTからパフォーマンスが低下しています。説明のプランは、SORT(GROUP BY)を実行していることを示しています。これは正しく発音しません。私はある種のHASH集約がもっと良い結果を生み出すと期待しています。ソートではなくDISTINCTにHASHを使用するようOracleに指示するヒントはありますか? 同様の状況で/ * + USE_HASH_AGGREGATION * /を使用しましたが、DISTINCTでは機能しません。oracle distinct doing sort

これが私の元のクエリです:

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秒かかります。

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

+1:良いスポット、良い仕事、そして幸運。私もこれに興味を持っています。 – MatBailie

+0

各クエリの説明/実行計画を表示できますか?また、 'USE_HASH_AGGREGATION'ヒントは正式に文書化されていないことに注意してください。 –

+0

[dba.se]からクロス投稿:http://dba.stackexchange.com/questions/13028 –

答えて

2

どのように次のことをしようとしてについて: あなたはCOLにインデックスを持っていたし、USERID場合、それは、完全に解決する必要がありますインデックスとテーブルにまったく触れる必要はありません。

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

インデックスはテーブルが非常に広い場合に役立ちますが、ナンバーはナローテーブルのためインデックスが役立たないためです。 –