75 lines
2.3 KiB
Markdown
75 lines
2.3 KiB
Markdown
---
|
|
title: Create Indexes for Frequently Filtered Fields
|
|
impact: CRITICAL
|
|
impactDescription: 10-100x faster queries on large collections
|
|
tags: collections, indexes, performance, query-optimization
|
|
---
|
|
|
|
## Create Indexes for Frequently Filtered Fields
|
|
|
|
PocketBase uses SQLite which benefits significantly from proper indexing. Queries filtering or sorting on unindexed fields perform full table scans.
|
|
|
|
**Incorrect (no indexes on filtered fields):**
|
|
|
|
```javascript
|
|
// Querying without indexes
|
|
const posts = await pb.collection('posts').getList(1, 20, {
|
|
filter: 'author = "user123" && status = "published"',
|
|
sort: '-publishedAt'
|
|
});
|
|
// Full table scan on large collections - very slow
|
|
|
|
// API rules also query without indexes
|
|
// listRule: "author = @request.auth.id"
|
|
// Every list request scans entire table
|
|
```
|
|
|
|
**Correct (indexed fields):**
|
|
|
|
```javascript
|
|
// Create collection with indexes via Admin UI or migration
|
|
// In PocketBase Admin: Collection > Indexes > Add Index
|
|
|
|
// Common index patterns:
|
|
// 1. Single field index for equality filters
|
|
// CREATE INDEX idx_posts_author ON posts(author)
|
|
|
|
// 2. Composite index for multiple filters
|
|
// CREATE INDEX idx_posts_author_status ON posts(author, status)
|
|
|
|
// 3. Index with sort field
|
|
// CREATE INDEX idx_posts_status_published ON posts(status, publishedAt DESC)
|
|
|
|
// Queries now use indexes
|
|
const posts = await pb.collection('posts').getList(1, 20, {
|
|
filter: 'author = "user123" && status = "published"',
|
|
sort: '-publishedAt'
|
|
});
|
|
// Index scan - fast even with millions of records
|
|
|
|
// For unique constraints (e.g., slug)
|
|
// CREATE UNIQUE INDEX idx_posts_slug ON posts(slug)
|
|
```
|
|
|
|
**Index recommendations:**
|
|
- Fields used in `filter` expressions
|
|
- Fields used in `sort` parameters
|
|
- Fields used in API rules (`listRule`, `viewRule`, etc.)
|
|
- Relation fields (automatically indexed)
|
|
- Unique fields like slugs or codes
|
|
|
|
**Index considerations for SQLite:**
|
|
- Composite indexes work left-to-right (order matters)
|
|
- Too many indexes slow down writes
|
|
- Use `EXPLAIN QUERY PLAN` in SQL to verify index usage
|
|
- Partial indexes for filtered subsets
|
|
|
|
```sql
|
|
-- Check if index is used
|
|
EXPLAIN QUERY PLAN
|
|
SELECT * FROM posts WHERE author = 'user123' AND status = 'published';
|
|
-- Should show "USING INDEX" not "SCAN"
|
|
```
|
|
|
|
Reference: [SQLite Query Planning](https://www.sqlite.org/queryplanner.html)
|