Skip to content

Commit 40028b2

Browse files
author
Hein
committed
Add compound indexing tand performance utorial
1 parent df3fe74 commit 40028b2

File tree

3 files changed

+138
-1
lines changed

3 files changed

+138
-1
lines changed

mint.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,8 @@
401401
"pages": [
402402
"tutorials/client/data/overview",
403403
"tutorials/client/data/cascading-delete",
404-
"tutorials/client/data/sequential-id-mapping"
404+
"tutorials/client/data/sequential-id-mapping",
405+
"/tutorials/client/data/compound-indexing-query-performance"
405406
]
406407
}
407408
]
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
---
2+
title: Best Practices for Compound Indexing and Query Optimization in PowerSync
3+
description: In this tutorial we will show you the Best Practices for Compound Indexing and Query Optimization using the [PowerSync Web SDK](https://github.com/powersync-ja/powersync-js).
4+
sidebarTitle: Compound Indexing & Query Performance
5+
---
6+
7+
## Introduction
8+
9+
This tutorial outlines findings and recommendations based on extensive testing of compound indexes, query execution, and table performance using the [PowerSync Web SDK](https://github.com/powersync-ja/powersync-js).
10+
These best practices are designed to assist developers in optimizing their schemas and queries when working with large datasets.
11+
12+
## Key Findings
13+
14+
### 1. Compound Index Behavior
15+
16+
- Compound indexes significantly improve query performance when filters align with the indexed column order.
17+
- Queries that skip leading columns in a compound index result in full table scans, negating performance benefits.
18+
- Performance is consistent with SQLite's behavior as PowerSync uses SQLite under the hood.
19+
20+
### 2. Performance Benchmarks
21+
22+
Using a table with 1999 columns and 50k entries:
23+
24+
#### Queries with Leading Column Filters
25+
26+
```sql
27+
EXPLAIN QUERY PLAN SELECT * FROM dummy_table WHERE col1 = 'val1';
28+
```
29+
30+
- **Execution Time:** 256 ms
31+
- **Query Plan:** SEARCH dummy_table USING COMPOUND INDEX
32+
33+
#### Queries with Multiple Indexed Columns
34+
35+
```sql
36+
EXPLAIN QUERY PLAN SELECT * FROM dummy_table WHERE col1 = 'val1' AND col2 = 'val2';
37+
```
38+
39+
- **Execution Time:** 206
40+
- **Query Plan:** SEARCH dummy_table USING COMPOUND INDEX
41+
42+
#### Queries Skipping Leading Columns
43+
44+
```sql
45+
EXPLAIN QUERY PLAN SELECT * FROM dummy_table WHERE col2 = 'val2' AND col3 = 'val3';
46+
```
47+
48+
- **Execution Time:** 556 ms
49+
- **Query Plan:** SCAN dummy_table
50+
### Performance
51+
52+
| Query Type | Execution Time | Query Plan |
53+
|-----------------------------------|----------------|-------------------------------------|
54+
| Leading Column Filters | 253 ms | SEARCH dummy_table USING COMPOUND INDEX |
55+
| Multiple Indexed Columns | 206 ms | SEARCH dummy_table USING COMPOUND INDEX |
56+
| Skipping Leading Columns | 556 ms | SCAN dummy_table |
57+
### 3. Column Limitations
58+
59+
- PowerSync supports a maximum of 1,999 columns in a compound index, aligning with SQLite's limitations.
60+
- Queries including non-indexed columns slightly increase execution time but remain performant under typical workloads.
61+
62+
## Best Practices
63+
64+
### Schema Definition
65+
66+
Define compound indexes to match your most frequent query patterns:
67+
68+
```javascript
69+
import { column, Table } from '@powersync/web';
70+
71+
const todos = new Table(
72+
{
73+
list_id: column.text, // Foreign key to lists
74+
created_at: column.text, // Creation timestamp
75+
description: column.text, // Task description
76+
},
77+
{
78+
indexes: {
79+
list_created: ['list_id', 'created_at'],
80+
},
81+
}
82+
);
83+
```
84+
85+
### Query Optimization
86+
87+
#### Aligned Filters
88+
89+
Ensure that queries align with the column order of compound indexes:
90+
91+
```javascript
92+
const results = await powerSync.get(
93+
`SELECT * FROM todos WHERE list_id = ? AND created_at = ?`,
94+
['list1', '2025-01-26']
95+
);
96+
```
97+
98+
#### Skipping Leading Columns
99+
100+
For queries skipping leading columns, define additional indexes:
101+
102+
```javascript
103+
await powerSync.execute(
104+
`CREATE INDEX idx_description ON todos (description);`
105+
);
106+
```
107+
108+
### Advanced Scenarios
109+
110+
#### Testing Column Order
111+
112+
The order of indexed columns affects query performance:
113+
114+
```javascript
115+
// Create compound index with a different order
116+
await powerSync.execute(`CREATE INDEX idx_order ON todos (description, list_id);`);
117+
118+
// Query execution profiling
119+
console.time('Query with reordered index');
120+
await powerSync.get(
121+
`SELECT * FROM todos WHERE description = ? AND list_id = ?`,
122+
['Task 1', 'list1']
123+
);
124+
console.timeEnd('Query with reordered index');
125+
```
126+
127+
## Key Takeaways
128+
129+
- Define compound indexes aligned with your most frequent query patterns.
130+
- Avoid skipping leading columns in compound indexes; create additional indexes if necessary.
131+
132+
## Conclusion
133+
134+
By following these best practices and leveraging PowerSync's schema capabilities, developers can achieve significant performance gains and ensure scalability for their applications.
135+
The findings above can be integrated directly into PowerSync's documentation to assist other developers in navigating these challenges effectively.

tutorials/client/data/overview.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ description: "A collection of tutorials showcasing various data management strat
66
<CardGroup>
77
<Card title="Cascading Delete" icon="database" href="/tutorials/client/data/cascading-delete" horizontal/>
88
<Card title="Sequential ID Mapping" icon="database" href="/tutorials/client/data/sequential-id-mapping" horizontal/>
9+
<Card title="Compound Indexing & Query Performance" icon="database" href="/tutorials/client/data/compound-indexing-query-performance" horizontal/>
910
</CardGroup>

0 commit comments

Comments
 (0)