2010-03-22 24 views
6

Khi tôi cố gắng tạo một chỉ mục duy nhất trên một bảng lớn, tôi nhận được một lỗi contraint duy nhất. Chỉ số duy nhất trong trường hợp này là khóa tổng hợp gồm 4 cột.Oracle: Xác định các bản sao trong bảng không có chỉ mục

Có một cách hiệu quả để xác định các bản sao khác hơn:

select col1, col2, col3, col4, count(*) 
from Table1 
group by col1, col2, col3, col4 
having count(*) > 1 

Các giải thích kế hoạch trên cho thấy bảng quét toàn bộ với chi phí rất cao, và chỉ muốn tìm thấy nếu có một cách khác.

Cảm ơn!

+0

http://www.remote-dba.cc/oracle_tips_duplicate_rows.htm –

Trả lời

7

Trước tiên hãy thử tạo chỉ mục không phải duy nhất trên bốn cột này. Điều đó sẽ mất thời gian O (n log n), nhưng cũng sẽ giảm thời gian cần thiết để thực hiện select đến O (n log n).

Bạn đang ở một chút ràng buộc ở đây - bất kỳ cách nào bạn cắt nó, toàn bộ bảng phải được đọc trong ít nhất một lần. Thuật toán na ï ve chạy trong thời gian O (n), trừ khi trình tối ưu hóa truy vấn đủ thông minh để tạo chỉ mục/bảng tạm thời.

+3

Sau khi bạn đã giải quyết vấn đề không phải duy nhất của mình, bạn có thể thực thi ràng buộc duy nhất bằng cách sử dụng chỉ mục không duy nhất mà bạn đã tạo.Nó sẽ không cho phép bạn tạo chỉ mục duy nhất trong khi bạn có chỉ mục không phải duy nhất trên cùng một cột, vì vậy nếu bạn THỰC SỰ muốn một chỉ mục duy nhất, hãy tạo chỉ mục không duy nhất của bạn như tạo chỉ mục t_ix trên bảng 1 (col1, col2, col3 , col4,1); Với chữ ở cuối, nó sẽ không dừng lại bạn sau khi tạo chỉ mục duy nhất trên col1, col2, col3, col4 và sau đó thả chỉ mục không độc nhất –

+0

Tất cả các câu trả lời chỉ ra rằng không có cách nào dễ dàng thoát khỏi vấn đề này. Nhưng câu trả lời này cũng đã cho tôi một cách tiếp cận, vì vậy tôi chọn đây là câu trả lời tốt nhất cho vấn đề của tôi. Cảm ơn Jeff. –

1

Vì không có chỉ mục trên các cột đó, truy vấn sẽ phải quét toàn bộ bảng - không có cách nào khác để thực hiện, trừ khi một hoặc nhiều cột trong số đó đã được lập chỉ mục.

Bạn có thể tạo chỉ mục dưới dạng chỉ mục không phải duy nhất, sau đó chạy truy vấn để xác định các hàng trùng lặp (sẽ rất nhanh khi chỉ mục được tạo). Nhưng tôi nghi ngờ nếu thời gian kết hợp của việc tạo ra các chỉ số không duy nhất sau đó chạy truy vấn sẽ là bất kỳ ít hơn chỉ chạy truy vấn mà không có chỉ mục.

0

Tôi không nghĩ rằng có một cách nhanh hơn không may.

1

Thực tế, bạn cần tìm bản sao của mỗi hàng trong bảng. Không có cách nào để làm điều này một cách hiệu quả mà không có chỉ mục.

2

Bạn có thể sử dụng mệnh đề EXCEPTIONS INTO để bẫy các hàng trùng lặp.

Nếu bạn chưa có một bảng NGOẠI LỆ tạo một trang bằng các kịch bản cung cấp:

SQL> @$ORACLE_HOME/rdbms/admin/ultexcpt.sql 

Bây giờ bạn có thể cố gắng để tạo ra một hạn chế duy nhất như thế này

alter table Table1 
add constraint tab1_uq UNIQUE (col1, col2, col3, col4) 
exceptions into exceptions 
/

này sẽ thất bại nhưng bây giờ bảng EXCEPTIONS của bạn chứa danh sách tất cả các hàng có khóa chứa các bản sao, được ROWID xác định. Điều đó cung cấp cho bạn cơ sở để quyết định phải làm gì với các bản sao (xóa, đổi số, bất kỳ thứ gì).

chỉnh sửa

Như những người khác đã lưu ý bạn phải trả tiền chi phí quét bảng một lần. Cách tiếp cận này cung cấp cho bạn một tập hợp vĩnh viễn các hàng trùng lặp và ROWID là cách nhanh nhất để truy cập vào bất kỳ hàng đã cho nào.

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