Make calculations incremental
This commit is contained in:
@@ -16,16 +16,42 @@ async function calculateProductMetrics(startTime, totalProducts, processedCount
|
||||
const BATCH_SIZE = 5000;
|
||||
|
||||
try {
|
||||
// Skip flags are inherited from the parent scope
|
||||
const SKIP_PRODUCT_BASE_METRICS = 0;
|
||||
const SKIP_PRODUCT_TIME_AGGREGATES = 0;
|
||||
// Get last calculation timestamp
|
||||
const [lastCalc] = await connection.query(`
|
||||
SELECT last_calculation_timestamp
|
||||
FROM calculate_status
|
||||
WHERE module_name = 'product_metrics'
|
||||
`);
|
||||
const lastCalculationTime = lastCalc[0]?.last_calculation_timestamp || '1970-01-01';
|
||||
|
||||
// Get total product count if not provided
|
||||
if (!totalProducts) {
|
||||
const [productCount] = await connection.query('SELECT COUNT(*) as count FROM products');
|
||||
const [productCount] = await connection.query(`
|
||||
SELECT COUNT(DISTINCT p.pid) as count
|
||||
FROM products p
|
||||
LEFT JOIN orders o ON p.pid = o.pid AND o.updated > ?
|
||||
LEFT JOIN purchase_orders po ON p.pid = po.pid AND po.updated > ?
|
||||
WHERE p.updated > ?
|
||||
OR o.pid IS NOT NULL
|
||||
OR po.pid IS NOT NULL
|
||||
`, [lastCalculationTime, lastCalculationTime, lastCalculationTime]);
|
||||
totalProducts = productCount[0].count;
|
||||
}
|
||||
|
||||
if (totalProducts === 0) {
|
||||
console.log('No products need updating');
|
||||
return {
|
||||
processedProducts: 0,
|
||||
processedOrders: 0,
|
||||
processedPurchaseOrders: 0,
|
||||
success: true
|
||||
};
|
||||
}
|
||||
|
||||
// Skip flags are inherited from the parent scope
|
||||
const SKIP_PRODUCT_BASE_METRICS = 0;
|
||||
const SKIP_PRODUCT_TIME_AGGREGATES = 0;
|
||||
|
||||
if (isCancelled) {
|
||||
outputProgress({
|
||||
status: 'cancelled',
|
||||
@@ -116,8 +142,15 @@ async function calculateProductMetrics(startTime, totalProducts, processedCount
|
||||
LEFT JOIN orders o ON p.pid = o.pid
|
||||
AND o.canceled = false
|
||||
AND o.date >= DATE_SUB(CURDATE(), INTERVAL 90 DAY)
|
||||
WHERE p.updated > ?
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM orders o2
|
||||
WHERE o2.pid = p.pid
|
||||
AND o2.canceled = false
|
||||
AND o2.updated > ?
|
||||
)
|
||||
GROUP BY p.pid
|
||||
`);
|
||||
`, [lastCalculationTime, lastCalculationTime]);
|
||||
|
||||
// Populate temp_purchase_metrics
|
||||
await connection.query(`
|
||||
@@ -132,18 +165,34 @@ async function calculateProductMetrics(startTime, totalProducts, processedCount
|
||||
LEFT JOIN purchase_orders po ON p.pid = po.pid
|
||||
AND po.received_date IS NOT NULL
|
||||
AND po.date >= DATE_SUB(CURDATE(), INTERVAL 365 DAY)
|
||||
WHERE p.updated > ?
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM purchase_orders po2
|
||||
WHERE po2.pid = p.pid
|
||||
AND po2.updated > ?
|
||||
)
|
||||
GROUP BY p.pid
|
||||
`);
|
||||
`, [lastCalculationTime, lastCalculationTime]);
|
||||
|
||||
// Process updates in batches
|
||||
// Process updates in batches, but only for affected products
|
||||
let lastPid = 0;
|
||||
while (true) {
|
||||
if (isCancelled) break;
|
||||
|
||||
const [batch] = await connection.query(
|
||||
'SELECT pid FROM products WHERE pid > ? ORDER BY pid LIMIT ?',
|
||||
[lastPid, BATCH_SIZE]
|
||||
);
|
||||
const [batch] = await connection.query(`
|
||||
SELECT DISTINCT p.pid
|
||||
FROM products p
|
||||
LEFT JOIN orders o ON p.pid = o.pid AND o.updated > ?
|
||||
LEFT JOIN purchase_orders po ON p.pid = po.pid AND po.updated > ?
|
||||
WHERE p.pid > ?
|
||||
AND (
|
||||
p.updated > ?
|
||||
OR o.pid IS NOT NULL
|
||||
OR po.pid IS NOT NULL
|
||||
)
|
||||
ORDER BY p.pid
|
||||
LIMIT ?
|
||||
`, [lastCalculationTime, lastCalculationTime, lastPid, lastCalculationTime, BATCH_SIZE]);
|
||||
|
||||
if (batch.length === 0) break;
|
||||
|
||||
@@ -532,7 +581,7 @@ async function calculateProductMetrics(startTime, totalProducts, processedCount
|
||||
// If we get here, everything completed successfully
|
||||
success = true;
|
||||
|
||||
// Update calculate_status
|
||||
// Update calculate_status with current timestamp
|
||||
await connection.query(`
|
||||
INSERT INTO calculate_status (module_name, last_calculation_timestamp)
|
||||
VALUES ('product_metrics', NOW())
|
||||
|
||||
Reference in New Issue
Block a user