我有一个表有活动的非活动条目,活动= 1表示活动,活动= 0表示不活动。
我在这个表上有各种索引,但我只需要为活动条目维护索引,因为应用程序只查询活动数据。需要保留非活动数据,因为它可以再次变为活动状态,但这通常仅通过批量更新完成,无论如何都不会使用索引。
我注意到索引非活动条目(越来越多的活动条目)占用了相当多的空间。
Oracle(10g)中是否有办法做这样的事情:
create index an_idx on tab (active, col1, col2, ... , coln) where active = 1
?
以前的尝试:
我尝试使用基于函数的索引将active = 0
设置为第一列,如下所示:
create index an_idx on tab (decode(active, 1, 1, null), col1, col2, ... , coln)
但在这种情况下,Oracle似乎仍然会为非活动列编制索引。
答案 0 :(得分:12)
您的基本想法是正确的,但您需要将解码应用于所有列。只有当所有索引表达式都为NULL
时,才会对该行进行索引。
create index an_idx on tab (
decode(active, 1, col1, null),
...
decode(active, 1, coln, null)
)
当然,如果您希望查询使用此索引,则必须在WHERE子句中使用相同的表达式。
注意我不认为您希望在索引中包含表达式decode(active, 1, 1, null)
,因为它对于所有索引行都是常量。
答案 1 :(得分:8)
通过ACTIVE对表进行分区,创建本地索引,并使非活动分区的索引为UNUSABLE。这将消除索引非活动数据所花费的时间。
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;
但这种方法有一些潜在的缺点:
在Oracle 12c中,您可以使用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;
答案 2 :(得分:1)
我不认为这是可能的。有几个选项