Close Menu
  • Home
  • Oracle
    • ASM
    • Data Guard
    • RAC
  • Performance
  • Tools
  • Troubleshooting
  • Python
  • Shell Script
Search

Oracle RAC 12.2 on VMware Workstation – Post 3: Grid Infrastructure Installation

2026-04-05 Oracle By Henrique

Oracle RAC 12.2 on VMware Workstation — Post 1: VMware Networking and Openfiler Setup

2026-04-05 Oracle By Henrique

Oracle RAC 12.2 on VMware Workstation – Post 2: Oracle Linux Configuration and iSCSI

2026-04-05 Oracle By Henrique
YouTube LinkedIn RSS
  • About
  • Contact
  • Legal
    • Cookie Policy
    • Disclaimer
    • Privacy Policy
    • Terms of Use
  • RSS
  • English
    • Portuguese (Brazil)
Execute StepExecute Step
YouTube LinkedIn RSS
  • Home
  • Oracle
    • ASM
    • Data Guard
    • RAC
  • Performance
  • Tools
  • Troubleshooting
  • Python
  • Shell Script
Execute StepExecute Step
Home » DBMS_SPACE.CREATE_INDEX_COST – How to Estimate Index Size Before Creating It
Performance

DBMS_SPACE.CREATE_INDEX_COST – How to Estimate Index Size Before Creating It

HenriqueBy Henrique2026-03-217 Mins Read
Share
Facebook Twitter LinkedIn Pinterest Email Telegram WhatsApp

This post is also available in: Português (Portuguese (Brazil))

Before creating an index on a production table with millions of rows, the inevitable question is: how much space will it consume?

Creating an index without this estimate can cause serious problems — tablespace full during creation, unexpected storage impact, or simply a surprise on the cloud bill. The good news is that Oracle provides a native way to estimate this without actually creating the index.

In this article, I’ll show how to use DBMS_SPACE.CREATE_INDEX_COST to estimate index sizes before creating them, with practical examples, real validation, and limitations you need to know.


What CREATE_INDEX_COST Does

The DBMS_SPACE.CREATE_INDEX_COST procedure takes a CREATE INDEX statement as input and returns two estimates:

VariableWhat it represents
usedSpace needed for the index data (bytes) — the useful size
allocTotal space that will be allocated in the tablespace (bytes) — includes block overhead, extents, and metadata

The difference between the two is normal — Oracle allocates space in extents, so alloc is always larger than used.

Prerequisites

For accurate estimates:

  • The table where the index will be created must exist
  • Statistics on the table must be up to date (DBMS_STATS)
  • The more current the statistics, the better the estimate

Basic Example — Simple Index

Step 1 — Prepare the variables

SET SERVEROUTPUT ON
VARIABLE used_bytes NUMBER
VARIABLE alloc_bytes NUMBER

Step 2 — Estimate the size

EXEC DBMS_SPACE.CREATE_INDEX_COST( -
  'CREATE INDEX idx_orders_date ON orders(order_date)', -
  :used_bytes, -
  :alloc_bytes -
);

Step 3 — View the result in MB

SELECT
  ROUND(:used_bytes / 1024 / 1024, 2) AS used_mb,
  ROUND(:alloc_bytes / 1024 / 1024, 2) AS alloc_mb
FROM dual;

Result (example):

   USED_MB   ALLOC_MB
---------- ----------
     55.00     264.00

The estimate indicates the index will use ~55 MB of actual data and Oracle will allocate ~264 MB in the tablespace.


Composite Index Example (Multiple Columns)

EXEC DBMS_SPACE.CREATE_INDEX_COST( -
  'CREATE INDEX idx_orders_cust_date ON orders(customer_id, order_date)', -
  :used_bytes, -
  :alloc_bytes -
);

SELECT
  ROUND(:used_bytes / 1024 / 1024, 2) AS used_mb,
  ROUND(:alloc_bytes / 1024 / 1024, 2) AS alloc_mb
FROM dual;

Composite indexes are larger because each index entry stores values from all key columns.


Example with Specific Tablespace

If you want to estimate considering a tablespace with different extent configuration:

EXEC DBMS_SPACE.CREATE_INDEX_COST( -
  'CREATE INDEX idx_orders_date ON orders(order_date) TABLESPACE idx_ts', -
  :used_bytes, -
  :alloc_bytes -
);

Oracle considers the extent size of the idx_ts tablespace when calculating alloc.


Full Example — Create, Estimate, and Validate

Let’s build a scenario from scratch to demonstrate the estimate’s accuracy.

Create a test table

CREATE TABLE teste AS SELECT * FROM all_objects;

-- Insert more data to simulate volume
INSERT INTO teste (SELECT * FROM teste);
-- Repeat until you have significant volume (e.g., ~5 million rows)

COMMIT;

SELECT COUNT(*) FROM teste;

Gather statistics

BEGIN
  DBMS_STATS.GATHER_TABLE_STATS(
    ownname => USER,
    tabname => 'TESTE',
    method_opt => 'FOR ALL COLUMNS SIZE AUTO',
    cascade => TRUE
  );
END;
/

Estimate the index size

VARIABLE used_bytes NUMBER
VARIABLE alloc_bytes NUMBER

EXEC DBMS_SPACE.CREATE_INDEX_COST( -
  'CREATE INDEX idx_teste_objid ON teste(object_id)', -
  :used_bytes, -
  :alloc_bytes -
);

SELECT
  ROUND(:used_bytes / 1024 / 1024, 2) AS estimated_used_mb,
  ROUND(:alloc_bytes / 1024 / 1024, 2) AS estimated_alloc_mb
FROM dual;

Create the index and compare

CREATE INDEX idx_teste_objid ON teste(object_id);

SELECT
  segment_name,
  ROUND(bytes / 1024 / 1024, 2) AS actual_mb
FROM dba_segments
WHERE segment_name = 'IDX_TESTE_OBJID';

Compare estimate vs actual

Estimated alloc:   264.00 MB
Actual size:       262.44 MB
Difference:        ~0.6%

The estimate is usually very close to the actual value when statistics are current.


Estimating Table Sizes with CREATE_TABLE_COST

The same DBMS_SPACE package offers CREATE_TABLE_COST for estimating table sizes. Useful for capacity planning:

VARIABLE used_bytes NUMBER
VARIABLE alloc_bytes NUMBER

EXEC DBMS_SPACE.CREATE_TABLE_COST( -
  'USERS',          -- tablespace_name
  8000,             -- avg_row_size (bytes)
  1000000,          -- row_count
  0,                -- pct_free
  :used_bytes,      --
  :alloc_bytes      --
);

SELECT
  ROUND(:used_bytes / 1024 / 1024, 2) AS used_mb,
  ROUND(:alloc_bytes / 1024 / 1024, 2) AS alloc_mb
FROM dual;

Limitations and Considerations

Before blindly trusting the estimate, be aware of the limitations:

LimitationImpact
Stale statisticsIf table statistics are old or missing, the estimate will be inaccurate
Bitmap indexesCREATE_INDEX_COST does not work for bitmap index estimation
Domain indexes (Oracle Text, Spatial)Not supported
Function-based indexesWorks, but requires statistics on the expression to be gathered
Partitioned tablesThe estimate is for the entire table, not per individual partition
Index compressionIf you’ll use COMPRESS, actual size will be smaller than estimated
LOB columnsNot applicable — LOBs cannot be directly indexed

Golden rule

Always gather fresh statistics before running CREATE_INDEX_COST. Stale statistics = wrong estimate.

-- Gather before estimating
EXEC DBMS_STATS.GATHER_TABLE_STATS(USER, 'TABLE_NAME');

Reusable Script

Save this script for whenever you need to estimate indexes:

-- estimate_index.sql
-- Usage: @estimate_index.sql
-- Modify the CREATE INDEX below for your scenario

SET SERVEROUTPUT ON
VARIABLE used_bytes NUMBER
VARIABLE alloc_bytes NUMBER

EXEC DBMS_SPACE.CREATE_INDEX_COST( -
  'CREATE INDEX idx_name ON schema.table(col1, col2)', -
  :used_bytes, -
  :alloc_bytes -
);

SELECT
  'Estimate' AS type,
  ROUND(:used_bytes / 1024 / 1024, 2) AS used_mb,
  ROUND(:alloc_bytes / 1024 / 1024, 2) AS alloc_mb,
  ROUND(:alloc_bytes / 1024 / 1024 / 1024, 2) AS alloc_gb
FROM dual;

Conclusion

DBMS_SPACE.CREATE_INDEX_COST is an essential tool for any DBA who needs to plan before acting. In production environments with tables containing hundreds of millions of rows, creating an index without estimating space is an unnecessary risk.

The recommended workflow before creating any index in production:

  1. Gather fresh statistics on the table
  2. Estimate the size with CREATE_INDEX_COST
  3. Verify the tablespace has enough space
  4. Create the index with confidence

Simple, fast, and prevents surprises.


References:

  • Oracle PL/SQL Packages Reference — DBMS_SPACE.CREATE_INDEX_COST
  • Oracle PL/SQL Packages Reference — DBMS_SPACE.CREATE_TABLE_COST

create-index-cost dbms-space index oracle performance tuning
Share. Facebook Twitter Pinterest LinkedIn Tumblr Email WhatsApp
Previous ArticleORA-15221 — How to Fix “ASM Operation Requires compatible.asm of String or Higher”
Next Article OPATCHAUTO-72083 — Bootstrap Operations Failed When Patching Grid Infrastructure

Related Posts

Oracle

OPATCHAUTO-72115 — Previous Session Not Completed in Out-of-Place Patching

2026-03-30
Read More
Oracle

PRCA-1057 — ASM Password File Not Found by CRS

2026-03-25
Read More
Oracle

ORA-01623 — Orphan Thread Redo Log After RAC to Single Instance Migration

2026-03-23
Read More
Add A Comment
Leave A Reply Cancel Reply

Demo
Follow Me
  • Email
  • GitHub
  • LinkedIn
  • RSS
  • YouTube

INS-06006 – Passwordless SSH Connectivity Not Set Up

2026-02-2614 Views

ORA-29548 — How to Fix “Java System Class Reported” in Oracle Database

2026-03-0510 Views

PRVG-2002 — How to Fix “Encountered Error in Copying File” in Oracle RAC

2026-03-078 Views
Demo
Tags
alter-sequence asm clusterware create sequence datapatch grid-infrastructure Grid Infrastructure how-to identity-column identity column ins-08101 installation inventory iSCSI lab listener opatch opatchauto Openfiler openssh ora-01031 ORA-12547 ora-12777 orabasetab oracle oracle oracle-database oracle-home oracle-linux oracle-rac Oracle Database Oracle Linux Oracle RAC out-of-place passwordless-ssh patching patching prvg-2002 RAC Installation redo-log runcluvfy scp tns troubleshooting VMware
Execute Step
YouTube LinkedIn RSS
  • Home
  • About
  • Contact
  • RSS
  • English
    • Português (Portuguese (Brazil))
© 2026 ExecuteStep. Designed by ThemeSphere.

Type above and press Enter to search. Press Esc to cancel.

Ad Blocker Enabled!
Ad Blocker Enabled!
Our website is made possible by displaying online advertisements to our visitors. Please support us by disabling your Ad Blocker.