oracle index - ghdrako/doc_snipets GitHub Wiki
select * from user_indexes where table_name='PTLF_EPS'
select * from user_indexes where status='INVALID'
You can only have one active index on a given column list at a time. So you can't create new (visible) single column indexes on either of these columns. But you can include these columns in multi-column indexes.
Note that the column list has to exactly match an existing index. You can create indexes on the same columns in a different order. For example, you can create both of these indexes:
create index qz_o_cust_ord_i on qz_orders ( customer_id, order_id );
create index qz_o_ord_cust_i on qz_orders ( order_id, customer_id );
12c relaxed this restriction. You can create many indexes on the same column list, provided that: •Only one is visible •All the indexes have different unique, bitmap, reverse or partitioning properties
The implicit index created for primary keys is unique. So from 12.1 up you could create the index in choice 2, provided you make it invisible:
create table qz_orders (
order_id integer not null primary key,
customer_id integer not null,
order_datetime date not null
);
create index qz_order_i on qz_orders ( order_id ) invisible;
select index_name, uniqueness, visibility
from user_indexes
where table_name = 'QZ_ORDERS';
INDEX_NAME UNIQUENESS VISIBILITY
QZ_ORDER_I NONUNIQUE INVISIBLE
SYS_C0019368 UNIQUE VISIBLE
Oracle 11g feature: invisible index
create invisible index :
SQL > create index tst_invisble_idx on Employee(emp_name) invisible;
you can alter index to visible :
SQL > alter index tst_invisble_idx visible;
you can alter index to invisible again :
SQL > alter index tst_invisble_idx invisible;
to make all indexes invisible to the optimizer for users :
SQL> alter system set optimizer_user_invisible_indexes=true;
to show index invisible status :
SQL> show paramter invisible;
Uzycia indexow
-- lista uzyc indeksów z planów wykonan zapytan
select
d.object_name,
d.operation,
d.options,
count(1)
from
dba_hist_sql_plan d,
dba_hist_sqlstat h
where
d.object_owner <> 'SYS'
and
d.operation like '%INDEX%'
and
d.sql_id = h.sql_id
group by
d.object_name,
d.operation,
d.options
order by
1,2,3;
Monitoring
alter index employees_idx1 monitoring usage;
select index_name,monitoring,used from v$object_usage;
INDEX_NAME MONITORING USED
------------------- ------------------ -----------
EMPLOYEES_IDX1 YES YES
alter index employees_idx1 nomonitoring usage;
Unusable index
user_indexes,dba_idexes Status N/A - never in global index.Partitioned indexes will always have a status of N/A in the all_indexes view. VALID INVALID
dba_ind_partitions, user_ind_partitions This table contains all partitioned indexes, along with a status column. Its possible values are USABLE, UNUSABLE, and N/A. N/A - Partitioned indexes can go a level deeper and have their own subpartitioned indexes.
Oracle provides us with a third view named all_ind_subpartitions,user_ind_subpartitions and dba_ind_subpartitions. This time, though, we can only have two possible values, USABLE, and UNUSABLE. At this point, we can determine if our index is valid or not by looking at its partition's subpartition's status.
select
index_name
from
all_indexes
where
owner not in ('SYS', 'SYSTEM')
and
status != 'VALID'
and (
status != 'N/A'
or
index_name in (
select
index_name
from
all_ind_partitions
where
status != 'USABLE'
and (
status != 'N/A'
or
index_name in (
select
index_name
from
all_ind_subpartitions
where
status != 'USABLE'
)
)
)
);
alter index emp_email_uk unusable;
alter index i_emp_name modify partition p2_i_emp ename unusable;
select index_name as "INDEX OR PARTITION NAME", status
from dba_indexes
where status = 'UNUSABLE'
union all
select partition_name as "INDEX OR PARTITION NAME", status
from dba_ind_partitions
where status = 'UNUSABLE'
SELECT i.table_name, i.index_name, ip.partition_name,
i.status AS index_status, ip.status AS partition_status
FROM user_indexes i
JOIN user_ind_partitions ip
ON (i.index_name = ip.index_name )
ORDER BY i.table_name, i.index_name, ip.partition_name;
-- segment for index mark as unusable no longer exist
select p.partition_name, p.status as "part_status",
p.segment_created as "seg_created",
from user_ind_partitions p
-- create index as unusable
create index i_emp_ename ON employees_part (employee_id)
local (partition p1_i_emp_ename UNUSABLE, partition
p2_i_emp_ename);
select index_name as "INDEX OR PARTITION NAME", status
from user_indexes
where index_name = 'I_EMP_ENAME'
union all
select partition_name as "INDEX OR PARTITION NAME", status
from user_ind_partitions
where partition_name like '%I_EMP_ENAME%';
-- index UNUSABLE must be rebuild in order to mark usable again
alter index EMP_GLOBAL_HASH_IDX modify partition P2 unusable;
alter index EMP_GLOBAL_HASH_IDX rebuild partition P2;
alter table slog.base MODIFY PARTITION base$yyyy$mm REBUILD UNUSABLE LOCAL INDEXES;