If you’re migrating from Oracle to YugabyteDB, you may have run across the concept of orphaned indexes. In Oracle, there are views and flags that let you check if indexes have become detached from their parent tables. It’s natural to wonder: should I worry about the same issue in YugabyteDB?
This tip was written to address that concern. Spoiler: in YugabyteDB, the chance of seeing orphaned indexes is basically zero. But let’s walk through both sides.
What Is an Orphaned Index?
An orphaned index is one that:
● Still exists in the catalog
● But no longer has a valid parent table
These are usually a sign of failed DDL or catalog corruption.
Orphaned Indexes in Oracle
In Oracle, orphaned or unusable indexes can crop up in a few cases:
● After dropping partitions with
UPDATE INDEXES● Following a failed
DROP TABLEor partial DDL rollback● In rare catalog corruption scenarios
Oracle makes this visible through USER_INDEXES, ALL_INDEXES, and DBA_INDEXES. Some of these expose an ORPHANED_ENTRIES flag.
Example in Oracle:
SELECT index_name, table_name, orphaned_entries
FROM user_indexes
WHERE orphaned_entries = 'YES';
If rows appear, you’ve got some cleanup to do.
Orphaned Indexes in YugabyteDB
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.
In contrast, YugabyteDB (via its PostgreSQL-compatible YSQL layer) handles index dependencies automatically:
● Dropping a table automatically drops all its indexes.
● Dropping a partition (child table) automatically drops its local indexes.
● YugabyteDB does not yet support global indexes on partitioned tables — so there’s nothing to “go stale.”
👉 Translation: under normal operation, there’s essentially a 0% chance you’ll ever encounter orphaned indexes in YugabyteDB.
If you do see one, it’s likely the result of manual catalog tampering or a serious bug… Make sure to report this to YugabyteDB Support!
Still Want to Check? Here’s How.
Even though you shouldn’t need to, you can query system catalogs to double-check:
WITH idx AS (
SELECT
c.relname AS index_name,
t.relname AS table_name,
n.nspname AS index_schema
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
JOIN pg_index i ON i.indexrelid = c.oid
LEFT JOIN pg_class t ON t.oid = i.indrelid
WHERE c.relkind IN ('i','I') -- index, partitioned index
)
SELECT *
FROM idx
WHERE table_name IS NULL
ORDER BY index_schema, index_name;
Expected output in YugabyteDB: zero rows.
Bonus: Oracle-style USER_INDEXES View in YB
For migration scripts that expect an Oracle view, you can define:
CREATE OR REPLACE VIEW user_indexes AS
SELECT
c.relname AS index_name,
t.relname AS table_name,
CASE WHEN i.indisunique THEN 'UNIQUE' ELSE 'NONUNIQUE' END AS uniqueness,
CASE WHEN i.indisvalid THEN 'VALID' ELSE 'INVALID' END AS status,
CASE WHEN t.oid IS NULL THEN 'YES' ELSE 'NO' END AS orphaned_entries
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
JOIN pg_index i ON i.indexrelid = c.oid
LEFT JOIN pg_class t ON t.oid = i.indrelid
WHERE c.relkind IN ('i','I')
AND n.nspname = current_schema()
ORDER BY table_name, index_name;
Now you can run:
SELECT *
FROM user_indexes
WHERE orphaned_entries = 'YES';
Again, you should see no rows in a healthy YugabyteDB.
Summary
● If you’re migrating from Oracle, you may worry about orphaned indexes.
● In Oracle, they can exist in edge cases, hence the
ORPHANED_ENTRIESflag inUSER_INDEXES.● In YugabyteDB, the catalog is managed differently: orphaned indexes basically cannot occur.
● We created this tip to reassure Oracle-to-YB migrations and to show how you could check if you want.
Have Fun!
