?oracle Index Maintenance Overview (Database Box)
?oracle Index Maintenance Overview (Database Box)
Alireza Kamrani
22/10/2024
Today I will represent some useful of technically notes about Rebuilding of indexes.
One of the most controversial topics among DBAs is whether to rebuild indexes or not.
But it is so generic that the answer to the question depends on the database version, the index
type and the reasons behind doing it.
In most cases, we consider b-tree indexes for rebuilt. Note that b stands not for “binary” but
for “balanced”.
We create indexes mostly for performance reasons. If performance is the real concern, we
need to rst understand at least at high level how those indexes are organized.
The MOS note Lists All Indexes that Bene t from a Rebuild (Doc ID 122008.1) suggests that
indexes considered for rebuilt are indexes for which:
Another MOS article, Script to investigate a b-tree index structure (Doc ID 989186.1), provides
a script which is quite handy as it veri es the structure of a b-tree index based on the existing
table and index statistics.
– Estimate the size the index should be as optimal packing can be speci ed
– The index layout
This script keeps a history of the the data gathered in the INDEX_HIST table.
This can be useful to prevent a pattern in index rebuilding. The history log can be user de ned.
An another MOS article, Index Rebuild, the Need vs the Implications (Doc ID 989093.1),
speci es that the most common justi cations given for rebuilding an index are:
♦ However, as noted, the impact of rebuilding the index can be quite signi cant:
♦ An index coalesce is often preferred instead of an index rebuild. It has the following
advantages:
📍 Due to the reasons listed above, it is strongly advised not to rebuild indexes on a regular
basis but instead use proper diagnostics.
fi
fi
fi
fi
fi
fi
♦ Furthermore, here is my personal experience from rebuilding indexes: either drop and create
or simply rebuild. I have seen 3 main use cases:
2. Indexes get fragmented over time and occupy too much space.
There was a mission critical production database where data was about 10GB and the indexes
all together were about 3TB. You can release sometimes quite a lot of space.
3. Indexes should be in my opinion in a separate tablespace. Not where the data is.
If something gets wrong with the index tablespace: logical or physical corruption, or deleting
les unintentionally, then it is just a matter of time to recreate the indexes again.
Basically, the CF is calculated by performing a Full Index Scan and looking at the rowid of each
index entry. If the table block being referenced di ers from that of the previous index entry, the
CF is incremented. If the table block being referenced is the same as the previous index entry,
the CF is not incremented. So the CF gives an indication of how well ordered the data in the
table is in relation to the index entries (which are always sorted and stored in the order of the
index entries). The better (lower) the CF, the more e cient it would be to use the index as less
table blocks would need to be accessed to retrieve the necessary data via the index.
However, there’s a basic aw here. The CF calculation doesn’t take into consideration the fact
the referenced table block, although maybe di erent from theprevious one index entry, might
already have recently been accessed. As such, during an index scan, the table block being
accessed is almost certainly still cached in the bu er cache from the previous access, thereby
not reducing the e ectiveness of the index in any appreciable manner. A classic example of
this would be a table with a few freelists. Although the data being inserted is not ordered
precisely within the same data blocks, the data might actually be very well clustered within only
a few blocks of each other.
Picture a table with 100 rows being inserted by 2 sessions simultaneously, each inserting 50
rows based on an ordered sequence. With one freelist, the data is basically inserted in one
block rst and then once full a second table block. The data is therefore perfectly ordered/
clustered and the CF will evaluate to a value of 2 on such an indexed column. But with 2
freelists, one session could insert data into one block while the other session inserts into a
fi
fi
ff
ff
fl
ff
ff
ff
ffi
second block, with the ordered sequenced values being randomly distributed among the 2
blocks. The CF could now potentially evaluate to a value of 100 as the rows are jumbled or
“toggled” across the two blocks. This is a much much worse value (2 vs. 100) that can
adversely impact the CBO calculations, although the e ciency of such an index is really almost
identical as both table blocks are certain to be cached during an index scan regardless.
Be aware on creating composite index that usually have a higher CF instead of index creation
per columns, but another recommendation is that usually preferred composite index instead of
one column indexed.
So creating of index need many considerations and need a deep investigation.
♦ In Oracle 19c , there is a feature called Automatic Indexing that have 5 steps internally and
newd a period of time to analyze and calculate essentials metadata and informations about
work loads of database and have sime mode such as Reporting Only, Implementation, so on.
We all know that indexes are critical for database performance as they signi cantly speed up
query execution. However, managing indexes manually can be complex and time-consuming.
Automatic Index Optimization simpli es this process by monitoring database usage patterns,
identifying ine cient or redundant indexes, and optimizing them without requiring manual
intervention.
Consider a scenario where a large retail database experiences frequent query performance
issues due to ine cient indexing.
Automatic Index Optimization can help by continuously monitoring the workload, creating new
indexes where needed, dropping unused indexes, and rebuilding fragmented ones.
Might not be applicable everywhere so I would rather advise to exercise caution and test this in
a lower environment rst.
♦ In Oracle 21c, there is a new feature called Automatic Index Optimization. The optimization
process includes 3 actions:
• Compress: Compresses portions of the key values in an index segment (~3 times)
• Shrink: Merges the contents of index blocks where possible to free blocks for reuse
• Rebuild: Rebuilds an index to improve space usage and access speed
For a very long time, both DBAs and Developers, have been struggling with what indexes
should be created, what type of indexes they should be created as and what indexes should
be dropped from the database.
By far, the most interesting new feature of Oracle Database 19c is Automatic Index creation (AI
Creation).
In the long run, this is to be one of the most important features in the Oracle database. Note
that you cannot rebuild or change storage parameters an auto index!
Nice and useful capability for AI is that Oracle automatically rebuilds indexes that are marked
as “Unusable”.

ffi
ffi
fi
fi
ffi
fi
Also Automatic indexing capable to remove unusable auto indexes suggestions that has not
implement on Dmls automaticaly after 373 days (con gurable manually) and many views to
control automatica indexing processes and historical view information.
The Auto Indexing can be disabled at any time or can be set to set to reporting mode (new
auto indexes as created asinvisible indexes, so that they cannot be used in SQL) with the
following commands:
EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_MODE','OFF');
SQL> EXEC
DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_DEFAULT_TABLESPACE','AUTO_INDEX_TS')
;
Generally rebuild index when the clustering factor exceeds eight times the number of dirty
blocks in the base table, when the levels exceed two or when there are excessive brown nodes
in the index.
Another good options to release a large index space that can be released spaces is using
Move online to another Tablespace but this solution has some performance penalty on
workload and you should use when have a minimum workload.
Also internal index related BLOB columns can move online in new versions of databases.

fi
fi
♦ Another recommendations about Index Rebuilding when
index size is very large with fewer time:
1. PARALLEL Scan:
Start an index rebuild with a full- scan, and this full-scan can be parallelized according to your
cpu_count.
2. NOLOGGING:
You can also use the NOLOGGING option for super-fast index rebuilding. The only danger with
using nologging is that you must re-run the create index syntax if you perform a roll-forward
database recovery. Using nologging with create index can make index rebuilding up to 30%
faster.
4. Partial index :
this feature help you to olny have index on some vital partitioned table and older data that
consider as archived data.
5. Faster Disk:
Some shops will use temporary solid-state disk to speed-up the initial index writes and move
the index to platter disk storage at a later time.
Alter index rebuild parallel: During a "regular" index rebuild, an exclusive lock occurs as the
existing index is read. Hence, this command is designed for scheduled downtime periods
where there is no DML activity. However, this operation can be parallelized and run in
NOLOGGING mode:
ff
ff
Sql>alter index my_idx rebuild parallel 48 nologging;
alter index my_idx noparallel;
alter index my_idx logging;
SQL Server:
Microsoft recommends xing index fragmentation issues by rebuilding the index if the
fragmentation percentage of the index exceeds 30%, where it recommends xing the index
fragmentation issue by reorganizing the index if the index fragmentation percentage exceeds
5% and less than 30%.
In many cases, rebuilding an index blindly can result in a larger index structure than it was prior
to the rebuild.
If we rebuild an index before the index has had the opportunity to use its available free space,
an index rebuild can introduce more free space, not less.
Now this may not necessarily be a bad thing, but it’s another example of the index potentially
being bigger, not smaller after a rebuild.
Although you can use compression features on indexes but this not very easy con guration
and need to exactly parameters and optimizer tuning to achieve better performance.
Key Enhancements:
• Improved Index Selection Algorithms: Enhanced algorithms analyze the workload more
e ectively to determine the most bene cial indexes, reducing the risk of unnecessary or
redundant indexes.
• Automatic Index Validation: New mechanisms validate the e ectiveness of automatically
created indexes before making them visible to queries, ensuring they genuinely improve
performance.

ff
ffi
fi
fi
ff
fi
fi
• Periodic Re-Evaluation: The system periodically re-evaluates the e ectiveness of indexes to
adapt to changing workloads and remove or modify indexes that are no longer bene cial.
• Better Integration with Database Workload: Integration with workload capture and replay
features ensures that indexes are optimized based on realistic usage patterns.
• Enhanced Reporting and Monitoring: Improved reporting features provide detailed insights
into automatic indexing activities, making it easier for DBAs to monitor and understand the
impact of automatic indexing.
Automatic Indexing works by continuously monitoring the SQL workload, identifying
candidates for indexing, and automatically creating, validating, and managing these indexes.
DBAs can still con gure, manage, and monitor automatic indexing on the database.
BEGIN
DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_RETENTION_FOR_IDLE_INDEXES', 30); --
Retention period in days
END;
BEGIN
DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_SPACE_BUDGET', 50);
-- Space budget as a percentage of total space
END;
♦ Also in 23ai we see advanced features for indexing JSON data type:

Indexes for JSON Data
You can index scalar values in your JSON data using function-based indexes. In addition, you
can de ne a JSON search index, which is useful for both ad hoc structural queries and full-text
queries.
As always, function-based indexing is appropriate for queries that target particular functions,
which in the context of SQL/JSON functions means particular SQL/JSON path expressions.
This indexing is not very helpful for queries that are ad hoc, that is, arbitrary. De ne a function-
based index if you know that you will often query a particular path expression.
Regardless of the SQL data type you use to store JSON data, you can use a B-tree or bitmap
function-based index for SQL/JSON function json_value queries. Such an index targets a single
scalar JSON value.
A bitmap index can be appropriate wherever the number of possible values for the function is
small.
For example, you can use a bitmap index for json_valueif the values targeted are expected to
be few.
For JSON data that is stored as JSON type you can use a multivalue function-based index for
SQL/JSON condition json_exists.
Such an index targets scalarJSON values, either individually or (especially) as elements of a
JSON array.
Although a multivalue index can index a single scalar value, if you expect a path expression to
target such a value then it is more performant to use a B-tree or bitmap index.
Use a multivalue index especially to index a path expression that you expect to target an array
of scalar values.
SQL/JSON path expressions that contain lter expressions can be used in queries that pick up
a function-based index. But a path expression that you use to de ne a function-based index
cannot contain lter expressions.
If you query in an ad hoc manner then de ne a JSON search index. This is a general index,
not targeted to any speci c path expression. It is appropriate for structural queries, such as
looking for a JSON eld with a particular value, and for full-text queries using Oracle SQL
condition json_textcontains, such as looking for a particular word among various string values.
You can of course de ne both function-based indexes and a JSON search index for the same
JSON column.
A JSON search index is an Oracle Text (full-text) index designed speci cally for use with JSON
data.
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
♦ Creating Bitmap Indexes for JSON_VALUE
You can create a bitmap index for SQL/JSON function json_value. A bitmap index can be
appropriate whenever your queries target only a small set of JSON values.
Note: By default, a function-based index does not include NULL values. If ajson_value
expression that's used by an index returns NULL, then by default the index is not used when
obtaining a matching document. This implies that by default a function-based index isn't used
if NULL is used as lter predicate (for example,json_value ... IS NULL) or if json_valueis used in
an ORDER BY clause.
To index NULL values, and thus enable the use of json_value in an ORDER BY clause you need
to add a constant value (any value) to the index creation statement:

fi
fi
CREATE INDEX po_num_idx1 ON j_purchaseorder po
(po.po_document.PONumber.number(), 42);
♦ Oracle recommends that you create a function-based index for json_value using one of the
following forms. In each case the index can be used in both dot-notation and json_value
queries that lead to a scalar result of the speci ed JSON data type.
• Dot-notation syntax, with an item method applied to the value to be indexed. The indexed
values are only scalars of the data type speci ed by the item method.
• A json_value expression that speci es aRETURNING data type. It can optionally use ERROR
ON ERROR and NULL ON EMPTY. The indexed values are only scalars of the data type
speci ed by the RETURNING clause.
Indexes created in either of these ways can thus be used with both dot-notation queries and
json_valuequeries.
fi
fi
fi
fi
fi
♦ Maintaining Oracle Text Indexes:
When you use the CREATE INDEX statement without explicitly specifying parameters, the
system completes the following actions by default for all languages:
• Assumes that the text to be indexed is stored directly in a text column. The text column can
be of type CLOB, BLOB,BFILE, VARCHAR2, or CHAR.
• Detects the column type and uses ltering for the binary column types of BLOB and BFILE.
Most document formats are supported for ltering. If your column is plain text, the system
does not use ltering.
Note:For document ltering to work correctly in your system, you must ensure that your
environment is set up correctly to support the AUTO_FILTER lter.
• Assumes that the language of the text to index is the language speci ed in your database
setup.
• Uses the default stoplist for the language speci ed in your database setup. Stoplists identify
the words that the system ignores during indexing.
• Enables fuzzy and stemming queries for your language, if this feature is available for your
language.
You can always change the default indexing behavior by customizing your preferences and
specifying those preferences in the parameter string of CREATEINDEX.

fi
fi
fi
fi
fi
fi
fi
fi
fi
Incrementally Creating an Index with ALTER INDEX and
CREATE INDEX
The ALTER INDEX and CREATE INDEX statements support incrementally creating a global
CONTEXTindex.
• For a global index, use CREATE INDEX to support the NOPOPULATE keyword in the
REPLACE parameter of the REBUILDclause. By doing so, you can create indexes
incrementally. This keyword is valuable for creating Oracle Text indexes in large installations
that cannot a ord to have the indexing process running continuously.
• For a local index partition, modify the ALTER INDEX ... REBUILD partition ... parameters
('REPLACE ...') parameter string to support the NOPOPULATEkeyword.
• For a partition on a local index, CREATEINDEX ... LOCAL ... (partition ... parameters
('NOPOPULATE')) is supported. The partition-level POPULATEor NOPOPULATE keywords
override any POPULATE or NOPOPULATE speci ed at the index level.
Overview
Indexes with automatic maintenance are synchronized in the background without any user
intervention.
♦ Automatic maintenance is the default method for synchronizing Oracle Text CONTEXT and
search indexes (Oracle Text, JSON, and XML search indexes) that are created in Oracle
Database 23ai and later releases.
Both the automatic maintenance and synchronization (SYNC) methods involve processing
pending updates, inserts, and deletes to the base table.
However, the automatic maintenance and SYNC speci cations are orthogonal.
With SYNC (EVERY), which also enables automatic background synchronization, you must
manually specify sync interval using interval-string. Although SYNC (EVERY) allows you to
explicitly control the synchronization interval, automatic maintenance provides an e cient
usage of database resources especially when supporting multiple PDBs. In addition, SYNC
(EVERY) may result in excessive launching of background sync jobs, based on the user's
estimate of how frequently new index data may arrive.
♦ Rebuilding an Index
You can rebuild a valid index by using ALTER INDEX.
♦ Rebuilding an index does not allow most index settings to be changed. You might rebuild an
index when you want to index with a new preference.
An ALTER INDEX REBUILD 'rebuild_params' statement rebuilds the index using supplied
parameters. Spatial index creation involves creating and inserting index data, for each row in
the underlying table column being spatially indexed, into a table with a prescribed format. All
rows in the underlying table are processed before the insertion of index data is committed, and
this requires adequate rollback segment space.
The ONLINE keyword rebuilds the index without blocking the index; that is, queries can use the
spatial index while it is being rebuilt. However, after all queries issued during the rebuild
operation have completed, you must clean up the old index information by entering a SQL
statement in the following form:
The following example rebuilds OLDINDEX and speci es the tablespace in which to create the
index data table.
💢 Finally,
I hope you have come to the conclusion that rebuilding the index at any time will not solve your
performance problems and it is better to focus on modifying the structure of the tables ,
schema design and the type of indexes that can be used and focus on quey execution plans
and selectivity of your indexes with considering CF, also with improving the standard
infrastructure you can achieve to create better indexes to get better performance.
-------------------------------------
I hope this tutorial be useful for you.
Alireza Kamrani