📘 1. Index Scan
The database uses an index to find rows, but still has to go to the table (heap) to get the full row data.
🧠 Why?
- Because the index doesn’t contain all the columns the query needs.
🔍 Example:
SELECT name FROM users WHERE email = 'stanley@example.com';
``>
If you have an index only on `email`, PostgreSQL will:
- Use the index to find the row locations (row pointers).
- Then **go to the table** to fetch the `name` column.
✅ Faster than full table scan
❌ Still needs **extra I/O** to fetch full rows
---
## 📄 2. **Index-Only Scan**
> The database uses the **index alone** — no need to visit the table at all.
### 🧠 Why?
- Because the **index contains all the needed columns**.
- And the database is **sure** the rows are still visible (via visibility map in PostgreSQL).
### 🔍 Example:
```sql
SELECT email FROM users WHERE email = 'stanley@example.com';
📊 Summary Table
Feature | Index Scan | Index-Only Scan |
---|---|---|
Uses table (heap)? | ✅ Yes — to fetch full row | ❌ No — index has everything |
Speed | Fast | Faster (less disk I/O) |
Conditions | Index has only the filtering column | Index has all needed columns |
Use case | Filtering with other columns needed | Filtering + projecting only indexed data |
✅ Bonus Tip
Want more Index-Only Scans?
→ Use covering indexes:
CREATE INDEX idx_users_email_name ON users(email, name);
Now SELECT name FROM users WHERE email = ?
can be index-only too.