【发布时间】:2012-12-18 01:55:45
【问题描述】:
我正在为我们的网站开发一个销售排名小部件,它将按产品在“排行榜”或“畅销书”列表中的当前位置显示排序的产品(可以这么说)。
经过一番阅读,实现这一点的一个好方法似乎是简单的滚动销售平均算法,其中销售越近,权重越高。
示例:
$rolling_avg = ((4*$d1)+(3*$d2)+(2*$d3)+$d4+$d5+$d6+$d7)/13;
地点:
- $d1 = 过去 24 小时内的销售数量。
- $d2 = 过去 24-48 小时内的销售数量。
- $d3 = 过去 48-72 小时内的销售数量。
- $d4 = 过去 72-96 小时内的销售数量。
等等……
目前,我正在尝试在大约 50 万条记录的产品数据集上运行它,将计算出的排名插入到产品表中,以便以后可以查询。如果可能的话,我希望能够创建一个脚本来重新计算排名,并每 12 或 24 小时在 cron 上运行一次。
当前实施:
我当前的实现需要很长时间才能执行,而且我觉得需要在 SQL 级别完成更多的处理(SELECT 查询要少得多),但我不确定如何开始。
$products = mysql_query("SELECT * FROM products ORDER BY id DESC"); // <-- Est 450-500k rows.
while($product = mysql_fetch_array($products)) {
$product_id = $product['id'];
$d1 = mysql_query("SELECT COUNT(*) FROM orders WHERE (product_id = '$product_id') AND (sale_completed BETWEEN (NOW()-INTERVAL 24 HOUR) AND NOW())") or die(mysql_error);
$d1 = mysql_fetch_array($d1);
$d2 = mysql_query("SELECT COUNT(*) FROM orders WHERE (product_id = '$product_id') AND (sale_completed BETWEEN (NOW()-INTERVAL 48 HOUR) AND (NOW()-INTERVAL 24 HOUR))");
$d2 = mysql_fetch_array($d2);
$d3 = mysql_query("SELECT COUNT(*) FROM orders WHERE (product_id = '$product_id') AND (sale_completed BETWEEN (NOW()-INTERVAL 72 HOUR) AND (NOW()-INTERVAL 48 HOUR))");
$d3 = mysql_fetch_array($d3);
$d4 = mysql_query("SELECT COUNT(*) FROM orders WHERE (product_id = '$product_id') AND (sale_completed BETWEEN (NOW()-INTERVAL 96 HOUR) AND (NOW()-INTERVAL 72 HOUR))");
$d4 = mysql_fetch_array($d4);
$d5 = mysql_query("SELECT COUNT(*) FROM orders WHERE (product_id = '$product_id') AND (sale_completed BETWEEN (NOW()-INTERVAL 120 HOUR) AND (NOW()-INTERVAL 96 HOUR))");
$d5 = mysql_fetch_array($d5);
$d6 = mysql_query("SELECT COUNT(*) FROM orders WHERE (product_id = '$product_id') AND (sale_completed BETWEEN (NOW()-INTERVAL 144 HOUR) AND (NOW()-INTERVAL 120 HOUR))");
$d6 = mysql_fetch_array($d6);
$d7 = mysql_query("SELECT COUNT(*) FROM orders WHERE (product_id = '$product_id') AND (sale_completed BETWEEN (NOW()-INTERVAL 168 HOUR) AND (NOW()-INTERVAL 144 HOUR))");
$d7 = mysql_fetch_array($d7);
$d1 = $d1[0];
$d2 = $d2[0];
$d3 = $d3[0];
$d4 = $d4[0];
$d5 = $d5[0];
$d6 = $d6[0];
$d7 = $d7[0];
$rolling_avg = ((4*$d1)+(3*$d2)+(2*$d3)+$d4+$d5+$d6+$d7)/13;
mysql_query("UPDATE products SET rolling_sales = '$rolling_avg' WHERE id = '$product_id'");
}
不知道如何从这里优化/进步。但它肯定需要大量工作。
在提及之前,我知道 mysql_* 函数已被贬值,我将在 PDO 进入生产环境之前将其移至 PDO。
【问题讨论】:
-
有一种加权平均算法,通常可以提供更好的结果并且更容易计算:它使用指数衰减而不是您的 ad-hoc 函数。请参阅我对另一个问题的回答:stackoverflow.com/questions/8211558/…