Disclaimer. The following is AI generated. Please be sure what to do or be informed by a DBA. These are guidelines.
Scope & rules (important)
-
Indexes are vendor-managed (EUCOP)
-
NOT allowed:
-
creating indexes
-
dropping indexes
-
changing index structure
-
-
Allowed (standard DBA maintenance):
-
updating statistics
-
index coalesce / reorganize / rebuild (when justified)
-
-
When in doubt → consult EUCOP
GENERIC FLOW (Oracle & SQL Server)
1. Start with the query (not the index)
-
Identify slow SQL
-
Check execution plan
-
Verify if index is used
2. Fix statistics FIRST
Most issues are caused by stale stats, not bad indexes
3. Check index usage
-
Used for reads? (good)
-
Only updated by writes? (potential overhead)
4. Check structure (fragmentation / bloat)
Only relevant for:
-
high delete activity
-
high churn tables
-
large indexes
5. Apply minimal maintenance
-
update stats
-
light maintenance first
-
rebuild only if justified
6. Validate
-
compare execution plan
-
check reads / performance improvement
ORACLE – GUIDELINES
Key point
Oracle does NOT use fixed % thresholds like SQL Server.
Decisions are based on:
-
deleted leaf rows
-
index growth vs table
-
actual performance impact
1. Update statistics (always first)
DBMS_STATS.GATHER_SCHEMA_STATS(
ownname => ‘SCHEMA’,
cascade => TRUE
);
END;
/
2. Check execution plan
FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(NULL, NULL, ‘ALLSTATS LAST’));
3. Monitor index usage
ALTER INDEX index_name MONITORING USAGE;
SELECT * FROM V$OBJECT_USAGE;
ALTER INDEX index_name NOMONITORING USAGE;
4. Analyze index structure
ANALYZE INDEX index_name VALIDATE STRUCTURE;
SELECT name, lf_rows, del_lf_rows
FROM index_stats;
👉 Guideline (no hard rule):
-
high
DEL_LF_ROWS→ consider maintenance
5. Maintenance
Preferred (light)
Heavy (only if justified)
Use rebuild only when:
-
clear bloat / fragmentation
-
measurable performance issue
-
or EUCOP advises it
SQL SERVER – GUIDELINES
1. Update statistics
2. Check index usage
FROM sys.dm_db_index_usage_stats
WHERE database_id = DB_ID();
3. Check fragmentation
FROM sys.dm_db_index_physical_stats(
DB_ID(), NULL, NULL, NULL, ‘LIMITED’
);
4. Maintenance rules
| Fragmentation | Action |
|---|---|
| < 5% | Do nothing |
| 5–30% | REORGANIZE |
| > 30% | REBUILD |
5. Commands
Reorganize (light)
Rebuild (heavy)
STANDARD MAINTENANCE SCRIPTS
Oracle – scan ALL indexes (structure overview)
Yes, you can scan all indexes, but not in one single built-in view. You typically loop.
Generate analyze statements
FROM dba_indexes
WHERE owner = ‘SCHEMA’;
Then execute the output.
⚠️ Note:
-
INDEX_STATSonly holds one index at a time -
so this is typically used for targeted analysis, not full automation
Oracle – coalesce all indexes (safe baseline job)
FOR r IN (
SELECT owner, index_name
FROM dba_indexes
WHERE owner = ‘SCHEMA’
AND status = ‘VALID’
) LOOP
EXECUTE IMMEDIATE
‘ALTER INDEX ‘ || r.owner || ‘.’ || r.index_name || ‘ COALESCE’;
END LOOP;
END;
/
👉 Safe default:
-
low impact
-
no structure change
-
vendor-friendly
Oracle – rebuild all indexes (ONLY if approved)
FOR r IN (
SELECT owner, index_name
FROM dba_indexes
WHERE owner = ‘SCHEMA’
) LOOP
EXECUTE IMMEDIATE
‘ALTER INDEX ‘ || r.owner || ‘.’ || r.index_name || ‘ REBUILD ONLINE’;
END LOOP;
END;
/
⚠️ Only use:
-
during maintenance window
-
or with EUCOP approval
SQL Server – scan + maintain all indexes
Fragmentation overview
OBJECT_NAME(i.object_id) AS table_name,
i.name AS index_name,
ps.avg_fragmentation_in_percent,
ps.page_count
FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, ‘LIMITED’) ps
JOIN sys.indexes i
ON ps.object_id = i.object_id
AND ps.index_id = i.index_id
WHERE ps.page_count > 1000;
Automated maintenance (safe logic)
DECLARE @sql NVARCHAR(MAX) = ”;
SELECT @sql = @sql +
CASE
WHEN avg_fragmentation_in_percent > 30
THEN ‘ALTER INDEX [‘ + i.name + ‘] ON [‘ + OBJECT_NAME(i.object_id) + ‘] REBUILD WITH (ONLINE = ON);’ + CHAR(10)
WHEN avg_fragmentation_in_percent BETWEEN 5 AND 30
THEN ‘ALTER INDEX [‘ + i.name + ‘] ON [‘ + OBJECT_NAME(i.object_id) + ‘] REORGANIZE;’ + CHAR(10)
ELSE ”
END
FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, ‘LIMITED’) ps
JOIN sys.indexes i
ON ps.object_id = i.object_id
AND ps.index_id = i.index_id
WHERE ps.page_count > 1000;
EXEC sp_executesql @sql;
Key takeaways (short)
-
Stats first, always
-
Oracle ≠ SQL Server → no % rules in Oracle
-
Coalesce/reorganize before rebuild
-
Rebuild only with reason
-
Vendor (EUCOP) owns index design
-
You maintain, not redesign