| Lesson 8 | Data dictionary views about indexes |
| Objective | View information about indexes in the data dictionary using Oracle 23ai |
In relational theory, the database catalog (metadata) is just as important as the data itself. The catalog describes the logical schema (tables, columns, constraints), and it also records physical and operational structures (indexes, partitions, storage, and status). Oracle exposes its catalog through the data dictionary—a set of tables and views that report what exists and how it is defined.
This lesson focuses on the dictionary views that help you answer the most common index questions:
Oracle publishes many dictionary views in three “scope tiers.” You choose the tier based on privileges and your intent:
For index research inside your own schema, USER_INDEXES and USER_IND_COLUMNS are the primary starting point.
If you need cross-schema visibility, move up to the ALL_ or DBA_ equivalents.
The USER_INDEXES view describes index objects at a high level: name, type, table association, uniqueness, and many structural details.
It includes many columns; the list below highlights common ones you will use when auditing or troubleshooting.
INDEX_NAME |
Name of the index. |
INDEX_TYPE |
Type of index (for example NORMAL, BITMAP, FUNCTION-BASED, DOMAIN). |
TABLE_OWNER |
Schema that owns the base table associated with the index. |
TABLE_NAME |
Name of the base table associated with the index. |
UNIQUENESS |
Either UNIQUE or NONUNIQUE. |
TABLESPACE_NAME |
Tablespace where the index segment is stored. |
BLEVEL |
Depth of the B-tree structure (lower is generally better for read efficiency). |
LEAF_BLOCKS |
Number of leaf blocks in the index segment. |
DISTINCT_KEYS |
Count of distinct key values (helps you reason about selectivity). |
NUM_ROWS |
Row count associated with the index statistics (depends on stats freshness). |
-- 1) List indexes you own (names + type + table + uniqueness + tablespace)
SELECT index_name,
index_type,
table_name,
uniqueness,
tablespace_name
FROM user_indexes
ORDER BY table_name, index_name;
-- 2) Filter indexes for a single table (use uppercase table name unless quoted)
SELECT index_name,
index_type,
uniqueness,
tablespace_name
FROM user_indexes
WHERE table_name = 'EMPLOYEES'
ORDER BY index_name;
The USER_IND_COLUMNS view tells you which columns make up an index and in what order.
Column order is not cosmetic—multi-column indexes are only directly useful when predicates and join conditions align with the leading columns.
INDEX_NAME |
Name of the index. |
TABLE_NAME |
Name of the table associated with the index. |
COLUMN_NAME |
Name of the indexed column. |
COLUMN_POSITION |
Position of the column within the index key (1 = leading column). |
COLUMN_LENGTH |
Length of the column in the index definition. |
The most useful pattern is to join the two views so you can see the index definition in “human” form:
-- Show each index with its columns in order
SELECT ui.table_name,
ui.index_name,
ui.uniqueness,
ui.index_type,
uic.column_position,
uic.column_name
FROM user_indexes ui
JOIN user_ind_columns uic
ON ui.index_name = uic.index_name
ORDER BY ui.table_name, ui.index_name, uic.column_position;
This query is your fast audit for:
If you use partitioning, index metadata expands. At a minimum, know that partitioned indexes have dedicated dictionary views.
A commonly referenced one is USER_PART_INDEXES, which contains information about partitioned index definitions.
When you troubleshoot a partitioned workload, you often want to confirm whether an index is local/global and how partitions are aligned.
-- Identify partitioned indexes you own
SELECT index_name,
table_name
FROM user_part_indexes
ORDER BY table_name, index_name;
Partition-aware metadata becomes essential when you are rebuilding indexes by partition, exchanging partitions, or diagnosing unexpected plan changes after partition maintenance.
The same concepts exist across schemas:
ALL_INDEXES, DBA_INDEXESALL_IND_COLUMNS, DBA_IND_COLUMNSALL_PART_INDEXES, DBA_PART_INDEXES
Use ALL_* when you are analyzing objects granted to you (for example in an application schema).
Use DBA_* when you must audit database-wide indexing practices.
Not all indexes are “normal” B-trees. Oracle supports extensible indexing through indextypes, which underpin
domain indexes (indexes implemented by Oracle or a user-defined framework).
The ALL_INDEXTYPES view displays information about the indextypes accessible to the current user.
Related Views
DBA_INDEXTYPES displays information about all indextypes in the database.USER_INDEXTYPES displays information about the indextypes owned by the current user.Conceptually, indextypes matter because they tell you what “specialized” indexing capabilities exist in the database, and whether those index implementations are system-managed or require user-managed maintenance.
| Column | Datatype | NULL | Description |
|---|---|---|---|
| OWNER | VARCHAR2(30) | NOT NULL | Owner of the indextype |
| INDEXTYPE_NAME | VARCHAR2(30) | NOT NULL | Name of the indextype |
| IMPLEMENTATION_SCHEMA | VARCHAR2(30) | NOT NULL | Schema containing the indextype implementation (operators and implementation types) |
| IMPLEMENTATION_NAME | VARCHAR2(30) | NOT NULL | Name of the indextype implementation type |
| INTERFACE_VERSION | NUMBER | NOT NULL | Version of the indextype interface |
| IMPLEMENTATION_VERSION | NUMBER | NOT NULL | Version of the indextype implementation |
| NUMBER_OF_OPERATORS | NUMBER | Number of operators associated with the indextype | |
| PARTITIONING | VARCHAR2(10) |
Kinds of local partitioning supported by the indextype:
|
|
| ARRAY_DML | VARCHAR2(3) | Indicates whether the indextype supports array DML (YES) or not (NO) | |
| MAINTENANCE_TYPE | VARCHAR2(14) | Indicates whether the indextype is system-managed (SYSTEM_MANAGED) or user-managed (USER_MANAGED) |
When you are debugging a query plan or auditing indexing practices, you typically want four classes of facts:
The basic views in this lesson cover (1)–(3) directly. For deeper tuning, you will also use statistics-focused views (and you will correlate index metadata with query plans).
SELECT *
FROM user_indexes;
SELECT *
FROM all_indexes;
SELECT index_name,
table_name,
column_position,
column_name
FROM user_ind_columns
WHERE index_name = 'BIDDER_CLIENT_IDX'
ORDER BY column_position;
SELECT ui.index_name,
ui.uniqueness,
ui.index_type,
uic.column_position,
uic.column_name
FROM user_indexes ui
JOIN user_ind_columns uic
ON ui.index_name = uic.index_name
WHERE ui.table_name = 'EMPLOYEES'
ORDER BY ui.index_name, uic.column_position;
You rarely query these views without filtering. Start with table name and/or index name, then expand outward:
-- Find indexes in a specific tablespace (useful for “separate index tablespace” audits)
SELECT index_name, table_name, tablespace_name
FROM user_indexes
WHERE tablespace_name = 'INDEX_TBS'
ORDER BY table_name, index_name;
With these dictionary patterns, you can quickly answer “what indexes exist, how are they defined, and where are they stored?” The next lesson builds on that by showing how to drop indexes safely as part of index lifecycle management.