2012-02-14 26 views
10

Tôi nhận được hiệu suất kém từ DISTINCT. Kế hoạch giải thích cho thấy rằng nó đang làm SORT (GROUP BY) mà không đúng. Tôi mong đợi một loại kết hợp HASH để tạo ra kết quả tốt hơn nhiều. Có một gợi ý để nói cho oracle sử dụng HASH cho DISTINCT hơn là sắp xếp không? Tôi đã sử dụng/* + USE_HASH_AGGREGATION */trong các tình huống tương tự, nhưng nó không hoạt động cho DISTINCT.oracle khác biệt làm sắp xếp

Vì vậy, đây là câu hỏi ban đầu của tôi:

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

người dùng có hàng 30M, mỗi userid là có 12 lần. Truy vấn này mất 70 giây.

Bây giờ chúng ta viết lại nó như

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

Và phải mất 40 giây. Bây giờ, hãy thêm gợi ý để làm băm thay vì sắp xếp:

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

và mất 10 giây.

Nếu ai đó có thể giải thích cho tôi lý do tại sao điều này xảy ra hoặc làm cách nào tôi có thể đánh bại truy vấn đơn giản đầu tiên hoạt động tốt như câu hỏi thứ 3, điều đó thật tuyệt vời.
Lý do tôi quan tâm đến sự đơn giản của truy vấn là do các truy vấn này thực sự được tạo.

Kế hoạch: 1) chậm:

---------------------------------------------------------------------------------------------------------------------------------------------------- 
| 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) nhanh

-------------------------------------------------------------------------------------------------------------------------------------------- 
| 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: Điểm tốt, công việc tốt và may mắn. Tôi cũng bị cuốn hút bởi cái này. – MatBailie

+0

Bạn có thể hiển thị các kế hoạch giải thích/thực thi cho từng truy vấn không? Ngoài ra, người ta nên lưu ý rằng gợi ý 'USE_HASH_AGGREGATION' là chính thức không có giấy tờ. –

+0

Được đăng chéo từ [dba.se]: http://dba.stackexchange.com/questions/13028 –

Trả lời

2

sao bạn không thử những điều sau đây: Nếu bạn có một chỉ mục trên col và userid nó sẽ giải quyết hoàn toàn trong chỉ mục và không cần chạm vào bảng.

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

giúp nếu bảng rất rộng, nhưng số của tôi là dành cho bảng hẹp để chỉ mục không giúp được gì. –

Các vấn đề liên quan