More gemini suggested improvements for speed
This commit is contained in:
@@ -101,12 +101,6 @@ async function calculateSalesForecasts(startTime, totalProducts, processedCount
|
||||
|
||||
if (batch.length === 0) break;
|
||||
|
||||
// Create temporary tables for better performance
|
||||
await connection.query('DROP TEMPORARY TABLE IF EXISTS temp_historical_sales');
|
||||
await connection.query('DROP TEMPORARY TABLE IF EXISTS temp_sales_stats');
|
||||
await connection.query('DROP TEMPORARY TABLE IF EXISTS temp_recent_trend');
|
||||
await connection.query('DROP TEMPORARY TABLE IF EXISTS temp_confidence_calc');
|
||||
|
||||
// Create optimized temporary tables with indexes
|
||||
await connection.query(`
|
||||
CREATE TEMPORARY TABLE temp_historical_sales (
|
||||
@@ -128,25 +122,15 @@ async function calculateSalesForecasts(startTime, totalProducts, processedCount
|
||||
days_with_sales INT,
|
||||
first_sale DATE,
|
||||
last_sale DATE,
|
||||
PRIMARY KEY (pid),
|
||||
INDEX (days_with_sales),
|
||||
INDEX (last_sale)
|
||||
) ENGINE=MEMORY
|
||||
`);
|
||||
|
||||
await connection.query(`
|
||||
CREATE TEMPORARY TABLE temp_recent_trend (
|
||||
pid BIGINT NOT NULL,
|
||||
recent_avg_units DECIMAL(10,2),
|
||||
recent_avg_revenue DECIMAL(15,2),
|
||||
PRIMARY KEY (pid)
|
||||
) ENGINE=MEMORY
|
||||
`);
|
||||
|
||||
await connection.query(`
|
||||
CREATE TEMPORARY TABLE temp_confidence_calc (
|
||||
CREATE TEMPORARY TABLE temp_recent_stats (
|
||||
pid BIGINT NOT NULL,
|
||||
confidence_level TINYINT,
|
||||
recent_avg_units DECIMAL(10,2),
|
||||
recent_avg_revenue DECIMAL(15,2),
|
||||
PRIMARY KEY (pid)
|
||||
) ENGINE=MEMORY
|
||||
`);
|
||||
@@ -167,7 +151,7 @@ async function calculateSalesForecasts(startTime, totalProducts, processedCount
|
||||
GROUP BY o.pid, DATE(o.date)
|
||||
`, [batch.map(row => row.pid)]);
|
||||
|
||||
// Populate sales stats
|
||||
// Combine sales stats and recent trend calculations
|
||||
await connection.query(`
|
||||
INSERT INTO temp_sales_stats
|
||||
SELECT
|
||||
@@ -182,23 +166,40 @@ async function calculateSalesForecasts(startTime, totalProducts, processedCount
|
||||
GROUP BY pid
|
||||
`);
|
||||
|
||||
// Populate recent trend
|
||||
// Calculate recent averages
|
||||
await connection.query(`
|
||||
INSERT INTO temp_recent_trend
|
||||
INSERT INTO temp_recent_stats
|
||||
SELECT
|
||||
h.pid,
|
||||
AVG(h.daily_quantity) as recent_avg_units,
|
||||
AVG(h.daily_revenue) as recent_avg_revenue
|
||||
FROM temp_historical_sales h
|
||||
WHERE h.sale_date >= DATE_SUB(CURRENT_DATE, INTERVAL 30 DAY)
|
||||
GROUP BY h.pid
|
||||
pid,
|
||||
AVG(daily_quantity) as recent_avg_units,
|
||||
AVG(daily_revenue) as recent_avg_revenue
|
||||
FROM temp_historical_sales
|
||||
WHERE sale_date >= DATE_SUB(CURRENT_DATE, INTERVAL 30 DAY)
|
||||
GROUP BY pid
|
||||
`);
|
||||
|
||||
// Calculate confidence levels
|
||||
// Generate forecasts using temp tables - optimized version
|
||||
await connection.query(`
|
||||
INSERT INTO temp_confidence_calc
|
||||
REPLACE INTO sales_forecasts
|
||||
(pid, forecast_date, forecast_units, forecast_revenue, confidence_level, last_calculated_at)
|
||||
SELECT
|
||||
s.pid,
|
||||
s.pid,
|
||||
DATE_ADD(CURRENT_DATE, INTERVAL n.days DAY),
|
||||
GREATEST(0, ROUND(
|
||||
CASE
|
||||
WHEN s.days_with_sales >= n.days
|
||||
THEN COALESCE(r.recent_avg_units, s.avg_daily_units)
|
||||
ELSE s.avg_daily_units * (s.days_with_sales / n.days)
|
||||
END
|
||||
)),
|
||||
GREATEST(0, ROUND(
|
||||
CASE
|
||||
WHEN s.days_with_sales >= n.days
|
||||
THEN COALESCE(r.recent_avg_revenue, s.avg_daily_revenue)
|
||||
ELSE s.avg_daily_revenue * (s.days_with_sales / n.days)
|
||||
END,
|
||||
2
|
||||
)),
|
||||
LEAST(100, GREATEST(0, ROUND(
|
||||
(s.days_with_sales / 180.0 * 50) + -- Up to 50 points for history length
|
||||
(CASE
|
||||
@@ -213,47 +214,21 @@ async function calculateSalesForecasts(startTime, totalProducts, processedCount
|
||||
WHEN DATEDIFF(CURRENT_DATE, s.last_sale) <= 30 THEN 10
|
||||
ELSE 0
|
||||
END) -- Up to 20 points for recency
|
||||
))) as confidence_level
|
||||
FROM temp_sales_stats s
|
||||
`);
|
||||
|
||||
// Generate forecasts using temp tables
|
||||
await connection.query(`
|
||||
REPLACE INTO sales_forecasts
|
||||
(pid, forecast_date, forecast_units, forecast_revenue, confidence_level, last_calculated_at)
|
||||
SELECT
|
||||
s.pid,
|
||||
DATE_ADD(CURRENT_DATE, INTERVAL n.days DAY),
|
||||
GREATEST(0, ROUND(
|
||||
CASE
|
||||
WHEN s.days_with_sales >= n.days THEN COALESCE(t.recent_avg_units, s.avg_daily_units)
|
||||
ELSE s.avg_daily_units * (s.days_with_sales / n.days)
|
||||
END
|
||||
)),
|
||||
GREATEST(0, ROUND(
|
||||
CASE
|
||||
WHEN s.days_with_sales >= n.days THEN COALESCE(t.recent_avg_revenue, s.avg_daily_revenue)
|
||||
ELSE s.avg_daily_revenue * (s.days_with_sales / n.days)
|
||||
END,
|
||||
2
|
||||
)),
|
||||
c.confidence_level,
|
||||
))),
|
||||
NOW()
|
||||
FROM temp_sales_stats s
|
||||
LEFT JOIN temp_recent_stats r ON s.pid = r.pid
|
||||
CROSS JOIN (
|
||||
SELECT 30 as days
|
||||
UNION SELECT 60
|
||||
UNION SELECT 90
|
||||
) n
|
||||
LEFT JOIN temp_recent_trend t ON s.pid = t.pid
|
||||
LEFT JOIN temp_confidence_calc c ON s.pid = c.pid;
|
||||
`);
|
||||
|
||||
// Clean up temp tables
|
||||
await connection.query('DROP TEMPORARY TABLE IF EXISTS temp_historical_sales');
|
||||
await connection.query('DROP TEMPORARY TABLE IF EXISTS temp_sales_stats');
|
||||
await connection.query('DROP TEMPORARY TABLE IF EXISTS temp_recent_trend');
|
||||
await connection.query('DROP TEMPORARY TABLE IF EXISTS temp_confidence_calc');
|
||||
await connection.query('DROP TEMPORARY TABLE IF EXISTS temp_recent_stats');
|
||||
|
||||
lastPid = batch[batch.length - 1].pid;
|
||||
myProcessedProducts += batch.length;
|
||||
|
||||
Reference in New Issue
Block a user