perf(cleaner-history): parallelize batch fetching in searchBatches

Replace sequential for-loop with Promise.all so that matched batches
are fetched concurrently instead of one-by-one, reducing total query
latency from O(n) serial round-trips to a single parallel batch.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Misaka_Company
2026-04-17 12:42:07 +08:00
parent 622543fff4
commit f49f99fc0c

View File

@@ -1068,15 +1068,14 @@ export class CleanerOperationHistoryDAO {
return { batches: [], totalMatches: 0 } return { batches: [], totalMatches: 0 }
} }
// Fetch full nested data for each matched batch // Fetch full nested data for each matched batch (parallel)
const batches: CleanerSearchBatchResult[] = [] const batchResults = await Promise.all(
limitedBatchIds.map(async (batchId) => {
for (const batchId of limitedBatchIds) {
try { try {
const details = await this.getBatchDetails(batchId) const details = await this.getBatchDetails(batchId)
if (details.executions.length === 0) { if (details.executions.length === 0) {
continue return null
} }
// Derive batch stats from execution records // Derive batch stats from execution records
@@ -1112,19 +1111,23 @@ export class CleanerOperationHistoryDAO {
}) })
) )
batches.push({ return {
batch, batch,
executions: details.executions, executions: details.executions,
orders: ordersWithMaterials orders: ordersWithMaterials
}) } satisfies CleanerSearchBatchResult
} catch (error) { } catch (error) {
log.error('Error fetching batch data for search result', { log.error('Error fetching batch data for search result', {
operationType: 'SELECT', operationType: 'SELECT',
batchId, batchId,
error: error instanceof Error ? error.message : String(error) error: error instanceof Error ? error.message : String(error)
}) })
return null
} }
} })
)
const batches = batchResults.filter((r): r is CleanerSearchBatchResult => r !== null)
log.info('Search batches completed', { log.info('Search batches completed', {
operationType: 'SELECT', operationType: 'SELECT',