perf: 优化监控刷新与历史里程分页查询
This commit is contained in:
@@ -554,13 +554,19 @@ func buildDailyMileageSQL(query url.Values) SQLQuery {
|
||||
}
|
||||
countArgs := append([]any(nil), args...)
|
||||
args = append(args, limit, offset)
|
||||
fromSQL := `FROM vehicle_daily_mileage m
|
||||
LEFT JOIN vehicle_identity_binding b ON b.vin = m.vin
|
||||
// Both joins are one-to-one. Binding is needed during filtering only for
|
||||
// keyword/bound scope; energy never affects which mileage rows qualify.
|
||||
filterFromSQL := `FROM vehicle_daily_mileage m`
|
||||
if strings.EqualFold(strings.TrimSpace(query.Get("vehicleScope")), "bound") || strings.TrimSpace(query.Get("vin")) != "" {
|
||||
filterFromSQL += ` LEFT JOIN vehicle_identity_binding b ON b.vin = m.vin`
|
||||
}
|
||||
filterFromSQL += ` WHERE ` + strings.Join(where, " AND ")
|
||||
enrichmentSQL := ` LEFT JOIN vehicle_identity_binding b ON b.vin = m.vin
|
||||
LEFT JOIN vehicle_open_daily_energy h
|
||||
ON h.vin COLLATE utf8mb4_unicode_ci = m.vin COLLATE utf8mb4_unicode_ci
|
||||
AND h.stat_date = m.stat_date
|
||||
AND h.energy_type = 'HYDROGEN' AND h.quality_status IN ('OK','SUSPECT')
|
||||
WHERE ` + strings.Join(where, " AND ")
|
||||
AND h.energy_type = 'HYDROGEN' AND h.quality_status IN ('OK','SUSPECT')`
|
||||
|
||||
if query.Get("deduplicate") == "1" || strings.EqualFold(query.Get("deduplicate"), "true") {
|
||||
selectionOrder := `m.daily_mileage_km DESC, m.protocol ASC`
|
||||
dailyMileageExpression := `MAX(COALESCE(m.daily_mileage_km, 0))`
|
||||
@@ -570,30 +576,26 @@ WHERE ` + strings.Join(where, " AND ")
|
||||
dailyMileageExpression = `COALESCE(CAST(SUBSTRING_INDEX(GROUP_CONCAT(CAST(COALESCE(m.daily_mileage_km, 0) AS CHAR) ORDER BY ` + selectionOrder + `), ',', 1) AS DECIMAL(18,3)), 0)`
|
||||
pureHydrogenMileageExpression = `COALESCE(CAST(SUBSTRING_INDEX(GROUP_CONCAT(CAST(COALESCE(m.pure_hydrogen_mileage_km, 0) AS CHAR) ORDER BY ` + selectionOrder + `), ',', 1) AS DECIMAL(18,3)), 0)`
|
||||
}
|
||||
groupSQL := fromSQL + ` GROUP BY m.vin, m.stat_date`
|
||||
groupSQL := filterFromSQL + ` GROUP BY m.vin, m.stat_date`
|
||||
// LIMIT materializes the grouped page before enrichment. Keep the exact
|
||||
// original aggregate/priority rules, including independent maxima when no
|
||||
// enabled protocol priority was supplied.
|
||||
pageSQL := `SELECT m.vin, m.stat_date, ` +
|
||||
`COALESCE(CAST(SUBSTRING_INDEX(GROUP_CONCAT(CAST(m.latest_total_mileage_km - m.daily_mileage_km AS CHAR) ORDER BY ` + selectionOrder + `), ',', 1) AS DECIMAL(18,3)), 0) AS start_mileage_km, ` +
|
||||
`COALESCE(CAST(SUBSTRING_INDEX(GROUP_CONCAT(CAST(m.latest_total_mileage_km AS CHAR) ORDER BY ` + selectionOrder + `), ',', 1) AS DECIMAL(18,3)), 0) AS end_mileage_km, ` +
|
||||
dailyMileageExpression + ` AS daily_mileage_km, ` + pureHydrogenMileageExpression + ` AS pure_hydrogen_mileage_km, ` +
|
||||
`COALESCE(SUBSTRING_INDEX(GROUP_CONCAT(m.protocol ORDER BY ` + selectionOrder + `), ',', 1), '') AS protocol ` +
|
||||
groupSQL + ` ORDER BY m.stat_date DESC, m.vin ASC LIMIT ? OFFSET ?`
|
||||
built := SQLQuery{
|
||||
Text: `SELECT m.vin, COALESCE(MAX(NULLIF(b.plate, '')), '') AS plate, DATE_FORMAT(m.stat_date, '%Y-%m-%d') AS stat_date, ` +
|
||||
`COALESCE(CAST(SUBSTRING_INDEX(GROUP_CONCAT(CAST(m.latest_total_mileage_km - m.daily_mileage_km AS CHAR) ORDER BY ` + selectionOrder + `), ',', 1) AS DECIMAL(18,3)), 0) AS start_mileage_km, ` +
|
||||
`COALESCE(CAST(SUBSTRING_INDEX(GROUP_CONCAT(CAST(m.latest_total_mileage_km AS CHAR) ORDER BY ` + selectionOrder + `), ',', 1) AS DECIMAL(18,3)), 0) AS end_mileage_km, ` +
|
||||
dailyMileageExpression + ` AS daily_mileage_km, ` +
|
||||
pureHydrogenMileageExpression + ` AS pure_hydrogen_mileage_km, ` +
|
||||
`MAX(h.consumption_kg) AS hydrogen_consumption_kg, ` +
|
||||
`MAX(h.consumption_kg_per_100km) AS hydrogen_consumption_kg_per_100km, ` +
|
||||
`MAX(h.soc_balanced_consumption_kg) AS hydrogen_soc_balanced_kg, ` +
|
||||
`MAX(h.soc_balanced_kg_per_100km) AS hydrogen_soc_balanced_kg_per_100km, ` +
|
||||
`MAX(h.pure_electric_mileage_km) AS pure_electric_mileage_km, ` +
|
||||
`MAX(h.mixed_mileage_km) AS mixed_mileage_km, ` +
|
||||
`MAX(h.battery_soc_delta_pct) AS battery_soc_delta_pct, ` +
|
||||
`MAX(h.charge_count) AS charge_count, ` +
|
||||
`MAX(h.charge_energy_kwh) AS charge_energy_kwh, ` +
|
||||
`MAX(h.refuel_count) AS refuel_count, ` +
|
||||
`MAX(h.refuel_amount_kg) AS refuel_amount_kg, ` +
|
||||
`MAX(CASE WHEN h.evidence_json IS NOT NULL THEN 1 ELSE 0 END) AS hydrogen_evidence_available, ` +
|
||||
`COALESCE(MAX(h.quality_status), '') AS hydrogen_quality_status, ` +
|
||||
`COALESCE(MAX(h.quality_reason), '') AS hydrogen_quality_reason, ` +
|
||||
`COALESCE(MAX(h.algorithm_version), '') AS hydrogen_algorithm_version, ` +
|
||||
`COALESCE(SUBSTRING_INDEX(GROUP_CONCAT(m.protocol ORDER BY ` + selectionOrder + `), ',', 1), '') AS protocol ` +
|
||||
groupSQL + ` ORDER BY m.stat_date DESC, m.vin ASC LIMIT ? OFFSET ?`,
|
||||
Text: `SELECT m.vin, COALESCE(NULLIF(b.plate, ''), '') AS plate, DATE_FORMAT(m.stat_date, '%Y-%m-%d') AS stat_date, ` +
|
||||
`m.start_mileage_km, m.end_mileage_km, m.daily_mileage_km, m.pure_hydrogen_mileage_km, ` +
|
||||
`h.consumption_kg AS hydrogen_consumption_kg, h.consumption_kg_per_100km AS hydrogen_consumption_kg_per_100km, ` +
|
||||
`h.soc_balanced_consumption_kg AS hydrogen_soc_balanced_kg, h.soc_balanced_kg_per_100km AS hydrogen_soc_balanced_kg_per_100km, ` +
|
||||
`h.pure_electric_mileage_km, h.mixed_mileage_km, h.battery_soc_delta_pct, h.charge_count, h.charge_energy_kwh, h.refuel_count, h.refuel_amount_kg, ` +
|
||||
`CASE WHEN h.evidence_json IS NOT NULL THEN 1 ELSE 0 END AS hydrogen_evidence_available, ` +
|
||||
`COALESCE(h.quality_status, '') AS hydrogen_quality_status, COALESCE(h.quality_reason, '') AS hydrogen_quality_reason, ` +
|
||||
`COALESCE(h.algorithm_version, '') AS hydrogen_algorithm_version, m.protocol ` +
|
||||
`FROM (` + pageSQL + `) m` + enrichmentSQL + ` ORDER BY m.stat_date DESC, m.vin ASC`,
|
||||
Args: args,
|
||||
CountText: `SELECT COUNT(*) FROM (SELECT m.vin ` + groupSQL + `) vehicle_daily_mileage_count`,
|
||||
CountArgs: countArgs,
|
||||
@@ -612,9 +614,9 @@ WHERE ` + strings.Join(where, " AND ")
|
||||
`h.soc_balanced_kg_per_100km, h.pure_electric_mileage_km, h.mixed_mileage_km, h.battery_soc_delta_pct, ` +
|
||||
`h.charge_count, h.charge_energy_kwh, h.refuel_count, h.refuel_amount_kg, CASE WHEN h.evidence_json IS NOT NULL THEN 1 ELSE 0 END, ` +
|
||||
`COALESCE(h.quality_status, ''), COALESCE(h.quality_reason, ''), COALESCE(h.algorithm_version, ''), m.protocol ` +
|
||||
fromSQL + ` ORDER BY m.stat_date DESC, m.vin ASC, m.protocol ASC LIMIT ? OFFSET ?`,
|
||||
`FROM (SELECT m.* ` + filterFromSQL + ` ORDER BY m.stat_date DESC, m.vin ASC, m.protocol ASC LIMIT ? OFFSET ?) m` + enrichmentSQL + ` ORDER BY m.stat_date DESC, m.vin ASC, m.protocol ASC`,
|
||||
Args: args,
|
||||
CountText: `SELECT COUNT(*) ` + fromSQL,
|
||||
CountText: `SELECT COUNT(*) ` + filterFromSQL,
|
||||
CountArgs: countArgs,
|
||||
}
|
||||
if query.Get("skipCount") == "1" || strings.EqualFold(query.Get("skipCount"), "true") {
|
||||
|
||||
Reference in New Issue
Block a user