lfqian commited on
Commit
4050e19
·
1 Parent(s): 4258b89

Optimize data fetching: remove date range query and per-agent DB queries for better performance

Browse files
Files changed (1) hide show
  1. src/lib/dataService.js +35 -56
src/lib/dataService.js CHANGED
@@ -140,26 +140,39 @@ class DataService {
140
  async _fetchAllFromRemote() {
141
  // First, get the max date from DB to know what we're aiming for
142
  let dbMaxDate = null
 
143
  try {
144
- const { data: maxDateData, error: maxDateError } = await supabase
145
- .from('trading_decisions')
146
- .select('date')
147
- .order('date', { ascending: false })
148
- .limit(1)
149
- if (!maxDateError && maxDateData && maxDateData.length > 0) {
150
- dbMaxDate = maxDateData[0].date
151
- console.log(`[DataService] Target max date from DB: ${dbMaxDate}`)
 
 
 
 
 
 
 
 
 
 
152
  }
 
153
  } catch (e) {
154
- console.error('[DataService] Error getting DB max date:', e)
155
  }
156
 
 
 
 
157
  const pageSize = 1000
158
  let from = 0
159
- const all = []
160
  let pageCount = 0
161
- let lastFetchedDate = null
162
-
163
  while (true) {
164
  const to = from + pageSize - 1
165
  pageCount++
@@ -187,7 +200,7 @@ class DataService {
187
  // Track the last date in this page
188
  const pageDates = pageData.map(r => r && r.date).filter(Boolean).sort()
189
  if (pageDates.length > 0) {
190
- lastFetchedDate = pageDates[pageDates.length - 1]
191
  console.log(`[DataService] Page ${pageCount}: ${pageData.length} rows, date range: ${pageDates[0]} to ${lastFetchedDate}`)
192
  }
193
 
@@ -197,33 +210,29 @@ class DataService {
197
  break
198
  }
199
 
200
- // Continue to next page - don't stop early based on date comparison
201
- // because pagination with order('date', ascending: true) might have
202
- // multiple pages with the same date, and we need to fetch all pages
203
  from += pageSize
204
  }
205
 
206
- // Log the final date range
207
  if (all.length > 0) {
208
  const dates = all.map(r => r && r.date).filter(Boolean).sort()
209
  const fetchedMinDate = dates[0]
210
  const fetchedMaxDate = dates[dates.length - 1]
211
- console.log(`[DataService] Total fetched: ${all.length} rows across ${pageCount} pages, date range: ${fetchedMinDate} to ${fetchedMaxDate}`)
212
  console.log(`[DataService] Last 10 dates:`, dates.slice(-10))
213
 
214
- // Verify we got the max date - if not, fetch missing data by date range
215
  if (dbMaxDate) {
216
  const fetchedMaxDateStr = typeof fetchedMaxDate === 'string' ? fetchedMaxDate.split('T')[0] : fetchedMaxDate
217
  const dbMaxDateStr = typeof dbMaxDate === 'string' ? dbMaxDate.split('T')[0] : dbMaxDate
218
  console.log(`[DataService] Verification: DB max date = ${dbMaxDateStr}, Fetched max date = ${fetchedMaxDateStr}`)
219
 
220
  if (fetchedMaxDateStr !== dbMaxDateStr && fetchedMaxDateStr < dbMaxDateStr) {
221
- console.warn(`[DataService] Missing data detected! DB has ${dbMaxDateStr} but we only fetched up to ${fetchedMaxDateStr}`)
222
  console.log(`[DataService] Fetching missing data from ${fetchedMaxDateStr} to ${dbMaxDateStr}...`)
223
 
224
- // Fetch all data from the day after fetchedMaxDate to dbMaxDate
225
- // Use gte (greater than or equal) to include the next day
226
- const nextDay = new Date(fetchedMaxDateStr)
227
  nextDay.setUTCDate(nextDay.getUTCDate() + 1)
228
  const nextDayStr = nextDay.toISOString().split('T')[0]
229
 
@@ -236,13 +245,12 @@ class DataService {
236
 
237
  if (!missingError && missingData && missingData.length > 0) {
238
  console.log(`[DataService] Fetched ${missingData.length} missing rows`)
239
- // Merge missing data, avoiding duplicates by id
240
  const existingIds = new Set(all.map(r => r.id))
241
  const newRows = missingData.filter(r => !existingIds.has(r.id))
242
  all.push(...newRows)
243
- console.log(`[DataService] Added ${newRows.length} new rows (${missingData.length - newRows.length} duplicates skipped)`)
244
 
245
- // Re-sort all data by date
246
  all.sort((a, b) => {
247
  const dateA = typeof a.date === 'string' ? a.date.split('T')[0] : a.date
248
  const dateB = typeof b.date === 'string' ? b.date.split('T')[0] : b.date
@@ -251,10 +259,6 @@ class DataService {
251
 
252
  const finalDates = all.map(r => r && r.date).filter(Boolean).sort()
253
  console.log(`[DataService] After fetching missing data: ${all.length} total rows, date range: ${finalDates[0]} to ${finalDates[finalDates.length - 1]}`)
254
- } else if (missingError) {
255
- console.error(`[DataService] Failed to fetch missing data:`, missingError)
256
- } else {
257
- console.warn(`[DataService] No missing data found (this might indicate a data inconsistency)`)
258
  }
259
  } else if (fetchedMaxDateStr === dbMaxDateStr) {
260
  console.log(`[DataService] ✓ Successfully fetched all data up to ${dbMaxDateStr}`)
@@ -323,7 +327,7 @@ class DataService {
323
  .sort()
324
  const start_date = dates[0] || '-'
325
 
326
- // 计算 end_date:先从已获取的数据计算,然后查询数据库获取该 agent 的最新日期
327
  let end_date = '-'
328
  if (seqFiltered.length > 0) {
329
  const lastRow = seqFiltered[seqFiltered.length - 1]
@@ -332,31 +336,6 @@ class DataService {
332
  end_date = dates[dates.length - 1]
333
  }
334
 
335
- // 查询数据库获取该 agent 的最新日期,确保 end_date 是最新的
336
- try {
337
- const { data: agentMaxDateData, error: agentMaxDateError } = await supabase
338
- .from('trading_decisions')
339
- .select('date')
340
- .eq('agent_name', row.agent_name)
341
- .eq('asset', row.asset)
342
- .eq('model', row.model)
343
- .order('date', { ascending: false })
344
- .limit(1)
345
-
346
- if (!agentMaxDateError && agentMaxDateData && agentMaxDateData.length > 0) {
347
- const dbAgentMaxDate = agentMaxDateData[0].date
348
- const dbAgentMaxDateStr = typeof dbAgentMaxDate === 'string' ? dbAgentMaxDate.split('T')[0] : dbAgentMaxDate
349
-
350
- // 如果数据库中的日期更新,使用数据库的日期
351
- if (dbAgentMaxDateStr && (!end_date || end_date === '-' || dbAgentMaxDateStr > end_date)) {
352
- console.log(`[DataService] STEP3.5 - ${row.agent_name}|${row.asset}|${row.model}: DB has newer date ${dbAgentMaxDateStr} than calculated ${end_date}, using DB date`)
353
- end_date = dbAgentMaxDateStr
354
- }
355
- }
356
- } catch (e) {
357
- console.error(`[DataService] Error querying DB for agent max date:`, e)
358
- }
359
-
360
  console.log(`[DataService] STEP3 - ${row.agent_name}|${row.asset}|${row.model}: Final end_date = ${end_date}, dates array length = ${dates.length}, seqFiltered length = ${seqFiltered.length}`)
361
  if (seqFiltered.length > 0) {
362
  const lastRowDate = seqFiltered[seqFiltered.length - 1].dateNormalized || (typeof seqFiltered[seqFiltered.length - 1].date === 'string' ? seqFiltered[seqFiltered.length - 1].date.split('T')[0] : seqFiltered[seqFiltered.length - 1].date)
 
140
  async _fetchAllFromRemote() {
141
  // First, get the max date from DB to know what we're aiming for
142
  let dbMaxDate = null
143
+ let dbMinDate = null
144
  try {
145
+ const [minDateResult, maxDateResult] = await Promise.all([
146
+ supabase
147
+ .from('trading_decisions')
148
+ .select('date')
149
+ .order('date', { ascending: true })
150
+ .limit(1),
151
+ supabase
152
+ .from('trading_decisions')
153
+ .select('date')
154
+ .order('date', { ascending: false })
155
+ .limit(1)
156
+ ])
157
+
158
+ if (!minDateResult.error && minDateResult.data && minDateResult.data.length > 0) {
159
+ dbMinDate = minDateResult.data[0].date
160
+ }
161
+ if (!maxDateResult.error && maxDateResult.data && maxDateResult.data.length > 0) {
162
+ dbMaxDate = maxDateResult.data[0].date
163
  }
164
+ console.log(`[DataService] DB date range: min = ${dbMinDate}, max = ${dbMaxDate}`)
165
  } catch (e) {
166
+ console.error('[DataService] Error getting DB date range:', e)
167
  }
168
 
169
+ const all = []
170
+
171
+ // Fetch all data using pagination (faster than date range query)
172
  const pageSize = 1000
173
  let from = 0
 
174
  let pageCount = 0
175
+
 
176
  while (true) {
177
  const to = from + pageSize - 1
178
  pageCount++
 
200
  // Track the last date in this page
201
  const pageDates = pageData.map(r => r && r.date).filter(Boolean).sort()
202
  if (pageDates.length > 0) {
203
+ const lastFetchedDate = pageDates[pageDates.length - 1]
204
  console.log(`[DataService] Page ${pageCount}: ${pageData.length} rows, date range: ${pageDates[0]} to ${lastFetchedDate}`)
205
  }
206
 
 
210
  break
211
  }
212
 
 
 
 
213
  from += pageSize
214
  }
215
 
216
+ // Log the final date range and verify - if missing data, fetch it
217
  if (all.length > 0) {
218
  const dates = all.map(r => r && r.date).filter(Boolean).sort()
219
  const fetchedMinDate = dates[0]
220
  const fetchedMaxDate = dates[dates.length - 1]
221
+ console.log(`[DataService] Total fetched: ${all.length} rows, date range: ${fetchedMinDate} to ${fetchedMaxDate}`)
222
  console.log(`[DataService] Last 10 dates:`, dates.slice(-10))
223
 
224
+ // Verify we got the max date - if not, fetch missing data
225
  if (dbMaxDate) {
226
  const fetchedMaxDateStr = typeof fetchedMaxDate === 'string' ? fetchedMaxDate.split('T')[0] : fetchedMaxDate
227
  const dbMaxDateStr = typeof dbMaxDate === 'string' ? dbMaxDate.split('T')[0] : dbMaxDate
228
  console.log(`[DataService] Verification: DB max date = ${dbMaxDateStr}, Fetched max date = ${fetchedMaxDateStr}`)
229
 
230
  if (fetchedMaxDateStr !== dbMaxDateStr && fetchedMaxDateStr < dbMaxDateStr) {
231
+ console.warn(`[DataService] Missing data detected! DB has ${dbMaxDateStr} but we fetched up to ${fetchedMaxDateStr}`)
232
  console.log(`[DataService] Fetching missing data from ${fetchedMaxDateStr} to ${dbMaxDateStr}...`)
233
 
234
+ // Fetch missing data by date range
235
+ const nextDay = new Date(fetchedMaxDateStr + 'T00:00:00.000Z')
 
236
  nextDay.setUTCDate(nextDay.getUTCDate() + 1)
237
  const nextDayStr = nextDay.toISOString().split('T')[0]
238
 
 
245
 
246
  if (!missingError && missingData && missingData.length > 0) {
247
  console.log(`[DataService] Fetched ${missingData.length} missing rows`)
 
248
  const existingIds = new Set(all.map(r => r.id))
249
  const newRows = missingData.filter(r => !existingIds.has(r.id))
250
  all.push(...newRows)
251
+ console.log(`[DataService] Added ${newRows.length} new rows`)
252
 
253
+ // Re-sort
254
  all.sort((a, b) => {
255
  const dateA = typeof a.date === 'string' ? a.date.split('T')[0] : a.date
256
  const dateB = typeof b.date === 'string' ? b.date.split('T')[0] : b.date
 
259
 
260
  const finalDates = all.map(r => r && r.date).filter(Boolean).sort()
261
  console.log(`[DataService] After fetching missing data: ${all.length} total rows, date range: ${finalDates[0]} to ${finalDates[finalDates.length - 1]}`)
 
 
 
 
262
  }
263
  } else if (fetchedMaxDateStr === dbMaxDateStr) {
264
  console.log(`[DataService] ✓ Successfully fetched all data up to ${dbMaxDateStr}`)
 
327
  .sort()
328
  const start_date = dates[0] || '-'
329
 
330
+ // 计算 end_date:从已获取的数据中提取,因为数据已经完整
331
  let end_date = '-'
332
  if (seqFiltered.length > 0) {
333
  const lastRow = seqFiltered[seqFiltered.length - 1]
 
336
  end_date = dates[dates.length - 1]
337
  }
338
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
339
  console.log(`[DataService] STEP3 - ${row.agent_name}|${row.asset}|${row.model}: Final end_date = ${end_date}, dates array length = ${dates.length}, seqFiltered length = ${seqFiltered.length}`)
340
  if (seqFiltered.length > 0) {
341
  const lastRowDate = seqFiltered[seqFiltered.length - 1].dateNormalized || (typeof seqFiltered[seqFiltered.length - 1].date === 'string' ? seqFiltered[seqFiltered.length - 1].date.split('T')[0] : seqFiltered[seqFiltered.length - 1].date)