🔎 PART 1 — How to Identify Index is Causing Performance Issue
✅ Step 1: Find Slow SQL (Entry Point)
Start from Top SQL, not from the index.
👉 Pick the problematic SQL
✅ Step 2: Check Execution Plan
🔍 Look for:
| Symptom | Meaning |
|---|---|
| FULL TABLE SCAN | Index missing or ignored ❌ |
| INDEX RANGE SCAN with high cost | Index inefficient ❌ |
| INDEX FULL SCAN | Poor selectivity ❌ |
✅ Step 3: Check Index Access Cost
In plan, observe:
CostRowsBytesBuffer Gets
👉 If index scan:
- Reads too many blocks → Index is not selective
✅ Step 4: Check Clustering Factor (Critical)
Interpretation:
- CF ≈ number of rows → ❌ Random reads (BAD index)
- CF ≈ number of blocks → ✅ Efficient index
👉 High CF → more I/O → slower query
✅ Step 5: Check Selectivity (Very Important)
👉 Formula:
Selectivity = num_distinct / num_rows
Result:
| Value | Meaning |
|---|---|
| High (close to 1) | ✅ Good index |
| Low (<0.1) | ❌ Bad index |
👉 Example:
status = 'ACTIVE'→ bad indexcustomer_id→ good index
✅ Step 6: Check If Index is Used Properly
Then:
SELECT * FROM v$object_usage WHERE index_name = 'INDEX_NAME';
👉 Result:
USED = NO→ Index uselessUSED = YES but slow→ Index is problem
✅ Step 7: Check Logical Reads (Performance Impact)
👉 High logical reads = heavy I/O → possible issue
✅ Step 8: Check Index BLEVEL (Depth)
| BLEVEL | Meaning |
|---|---|
| 0–2 | ✅ Good |
| 3–4 | ⚠️ Ok |
| >4 | ❌ Too deep |
✅ Step 9: Validate Stats
👉 Bad stats = wrong execution plan
✅ Step 10: Compare With Full Table Scan
Force test:
SELECT /*+ FULL(table_name) */ ..
👉 If FULL scan is faster → Index is hurting performance
🚨 Conclusion (Index Causing Issue If):
- High clustering factor
- Low selectivity
- High logical reads
- Not used or incorrectly used
- Execution plan shows inefficiency
✅ PART 2 — How to Check Index is GOOD or BAD
🎯 Step-by-Step Evaluation Framework
✅ Step 1: Usage Check
| Result | Decision |
|---|---|
| USED frequently | ✅ Good |
| NOT USED | ❌ Drop candidate |
✅ Step 2: Query Alignment
👉 Check if index matches WHERE clause:
WHERE col1 = :1 AND col2 = :2
👉 Good index:
(col1, col2)
👉 Bad index:
(col3, col4)
✅ Step 3: Selectivity Check
- High distinct values → ✅ Good
- Low distinct values → ❌ Bad
✅ Step 4: Clustering Factor
- Low CF → ✅ Good
- High CF → ❌ Bad
✅ Step 5: Size vs Benefit
👉 Large + rarely used → ❌ Bad
✅ Step 6: DML Overhead Check
👉 Too many indexes on high DML table:
- Slows INSERT/UPDATE/DELETE
👉 More indexes ≠ better
✅ Step 7: Redundancy Check
👉 Duplicate indexes = waste
✅ Step 8: BLEVEL + Leaf Blocks
👉 Small, compact index = good
👉 Huge fragmented index = bad
✅ FINAL DECISION MATRIX
| Condition | Good Index ✅ | Bad Index ❌ |
|---|---|---|
| Usage | Frequent | Not used |
| Execution Plan | Index scan | Full scan |
| Selectivity | High | Low |
| Clustering Factor | Low | High |
| BLEVEL | ≤2 | >4 |
| Size | Optimized | Huge unused |
| DML Impact | Low | High |
🔥 REAL-WORLD QUICK CHECK SCRIPT
💡 Architect-Level Insight (Important)
👉 Don’t judge index in isolation
Always evaluate:
SQL → Execution Plan → Index → Data Pattern
✅ Recommended Approach (Best Practice)
- Identify top SQL (AWR/V$SQL)
- Analyze execution plan
- Validate index usage
- Check clustering factor + selectivity
- Decide: KEEP / REBUILD / DROP
No comments:
Post a Comment