2011-10-05 30 views
7

Tôi có một bảng có các mục nhập không hoạt động, active = 1 cho active và active = 0 cho không hoạt động.Oracle: Lập chỉ mục một tập hợp con các hàng của một bảng

Tôi có nhiều chỉ mục trên bảng này, nhưng tôi chỉ cần các chỉ mục được duy trì cho các mục nhập hoạt động vì ứng dụng chỉ truy vấn dữ liệu đang hoạt động. Dữ liệu không hoạt động cần phải được lưu giữ bởi vì nó có thể hoạt động trở lại, nhưng điều này thường chỉ được thực hiện với các bản cập nhật hàng loạt, tuy nhiên sẽ không sử dụng chỉ mục.

Tôi nhận thấy việc lập chỉ mục các mục nhập không hoạt động (có ngày càng nhiều mục nhập hoạt động) chiếm khá nhiều không gian.

Có cách nào trong Oracle (10g) để làm một cái gì đó như thế này:

create index an_idx on tab (active, col1, col2, ... , coln) where active = 1?

nỗ lực trước:

tôi đã cố gắng sử dụng một chức năng chỉ số dựa để thiết lập cột đầu tiên để null khi active = 0 như vậy:

create index an_idx on tab (decode(active, 1, 1, null), col1, col2, ... , coln)

Tuy nhiên, Oracle vẫn dường như chỉ số cột không hoạt động trong trường hợp này.

Trả lời

7

Phân vùng bảng theo ACTIVE, tạo chỉ mục cục bộ và tạo chỉ mục cho phân vùng không hoạt động KHÔNG THÍCH. Điều này sẽ loại bỏ thời gian dành cho việc lập chỉ mục dữ liệu không hoạt động.

create table tab(active number, col1 number, col2 number, col3 number) 
    partition by list(active) 
    (partition tab_active values(1), partition tab_inactive values(0)); 

create index tab_index1 on tab(col1) local; 

alter index tab_index1 modify partition tab_inactive unusable; 

Nhưng có một số nhược điểm tiềm năng để tiếp cận này:

  • Không phải tất cả các loại chỉ số có thể sử dụng được.
  • Không bình thường khi có các đối tượng không sử dụng được trong cơ sở dữ liệu. Mọi người sẽ có khả năng phàn nàn về nó hoặc cho rằng đó là một lỗi và xây dựng lại nó.
  • Một số thao tác, chẳng hạn như cắt bớt, sẽ tự động làm cho các chỉ mục có thể sử dụng lại.

Trong Oracle 12c bạn có thể thực hiện điều này bằng partial indexes:

create table tab(active number, col1 number, col2 number, col3 number) 
    partition by list(active) 
    (partition tab_active values(1) indexing on, 
    partition tab_inactive values(0) indexing off); 

create index tab_index1 on tab(col1) local indexing partial; 
1

Tôi không nghĩ điều này là có thể. Có một vài tùy chọn

  1. Hãy một chỉ mục trên (hoạt động, col1 ...) do đó thời gian truy vấn không bị ảnh hưởng càng nhiều bởi các yếu tố không hoạt động
  2. Tạo hai bảng cho hoạt động/mục hoạt động và quản lý trạng thái hoạt động bằng cách di chuyển mọi thứ giữa hai bảng
  3. Tạo bảng thứ hai với tất cả dữ liệu bạn muốn lập chỉ mục cũng như số nhận dạng duy nhất và tham gia vào bảng để nhận phần còn lại của dữ liệu.
+0

Nếu tiết kiệm không gian là mục tiêu của bạn, phương án 2 sẽ có ý nghĩa IMO. –

11

Ý tưởng cơ bản của bạn là đúng, nhưng bạn cần áp dụng giải mã cho tất cả các cột. Chỉ khi tất cả các biểu thức được lập chỉ mục là NULL thì hàng sẽ không được lập chỉ mục.

create index an_idx on tab (
    decode(active, 1, col1, null), 
    ... 
    decode(active, 1, coln, null) 
) 

Tất nhiên, nếu sau đó bạn muốn có một truy vấn để sử dụng chỉ số này, nó phải sử dụng các từ ngữ tương tự trong mệnh đề WHERE.

Lưu ý Tôi không nghĩ rằng bạn muốn bao gồm cụm từ decode(active, 1, 1, null) trong chỉ mục vì nó sẽ là hằng số cho tất cả các hàng được lập chỉ mục.

+0

Cảm ơn bạn đã có giải pháp. Tôi đã lo lắng tôi sẽ phải làm một cái gì đó lộn xộn như thế này. Nghĩ rằng có thể có cái gì đó sạch hơn. – Clinton

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