Skip to content

Commit 7b96600

Browse files
perf(tables): run row count and page fetch concurrently in queryRows
1 parent 2ad40e2 commit 7b96600

2 files changed

Lines changed: 19 additions & 12 deletions

File tree

apps/sim/lib/table/__tests__/table-wrapper.test.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,8 +211,13 @@ describe('table-wrapper', () => {
211211
expect(dbChainMockFns.from).toHaveBeenCalledTimes(2)
212212
})
213213

214-
it('computes totalCount when includeTotal=true', async () => {
215-
dbChainMockFns.where.mockResolvedValueOnce([{ count: 7 }])
214+
it('computes totalCount concurrently when includeTotal=true', async () => {
215+
// The main query's `.where()` is built first (call #1), then the count
216+
// query's `.where()` (call #2) — both issued together via Promise.all.
217+
const defaultWhere = dbChainMockFns.where.getMockImplementation()!
218+
dbChainMockFns.where
219+
.mockImplementationOnce(defaultWhere)
220+
.mockResolvedValueOnce([{ count: 7 }])
216221
stubRowFetch([])
217222
const result = await queryRows(TABLE, { includeTotal: true, withExecutions: false })
218223
expect(result.totalCount).toBe(7)

apps/sim/lib/table/table-wrapper.ts

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -117,15 +117,6 @@ export async function queryRows(
117117
}
118118
}
119119

120-
let totalCount: number | null = null
121-
if (includeTotal) {
122-
const countResult = await db
123-
.select({ count: count() })
124-
.from(userTableRows)
125-
.where(whereClause ?? baseConditions)
126-
totalCount = Number(countResult[0].count)
127-
}
128-
129120
let orderByClause
130121
if (sort && Object.keys(sort).length > 0) {
131122
orderByClause = buildSortClause(sort, tableName, columns)
@@ -142,7 +133,18 @@ export async function queryRows(
142133
query = query.orderBy(userTableRows.position) as typeof query
143134
}
144135

145-
const rows = await query.limit(limit).offset(offset)
136+
// Count and page fetch are independent reads — run them concurrently so the
137+
// `includeTotal` hot path doesn't pay two serial round-trips.
138+
const rowsPromise = query.limit(limit).offset(offset)
139+
const countPromise = includeTotal
140+
? db
141+
.select({ count: count() })
142+
.from(userTableRows)
143+
.where(whereClause ?? baseConditions)
144+
: null
145+
146+
const [rows, countResult] = await Promise.all([rowsPromise, countPromise])
147+
const totalCount = countResult ? Number(countResult[0].count) : null
146148

147149
const executionsByRow = withExecutions
148150
? await loadExecutionsByRow(

0 commit comments

Comments
 (0)