注:1. foreach里面的查询无法取出一次性处理,复杂性会更大,性能不会太好
2. 这是一个全表扫的sql,需要计算每一个行的某个字段的值,每天都需要计算
$productList = $productsManage->getAllActiveProductList($fields, $params);
//print_r($productList);exit;
if (empty($productList)){
die('没有获取到产品信息');
}
$table = "erp_products_data";
$i = 0;
//开始循环来计算吧
foreach ($productList as $pro){
//SKU
$sku = trim($pro['products_sku']);
$warehouse = $pro['product_warehouse_id'];
$id = $pro['products_id'];
//计算利润率
$avgProfitRate = $getTotals->getSkuFiveAverage($sku);
//计算60天退款次数
$skuMoneybackCount = getSkuMoneybackCount($sku);
//计算各仓库的60天销量
$sold_60 = getSalesTotalInSalesRecordMinDays($sku, 60 ,$v['product_warehouse_id']);
$data = array();
$data['sold_60'] = $sold_60;
$data['backMoney_60'] = $skuMoneybackCount;
$data['profitRate_15'] = $avgProfitRate;
$where = " products_id=".$id;
$doSql->update($table, $data, $where);
if($i>100){
$end_time = microtime(true);
$ret_time = $end_time - $start_time ;
echo "Code execution time is ".$ret_time." second";
echo 'the end...';
exit;
}
$i++;
}
12 个解决方案
#1
目前我是把他拆分开 跑4次 性能还是不行
#2
#3
$data['sold_60'] = $sold_60;
$data['backMoney_60'] = $skuMoneybackCount;
$data['profitRate_15'] = $avgProfitRate;
这三个量是如何计算的?
瓶颈应该在这里
$data['backMoney_60'] = $skuMoneybackCount;
$data['profitRate_15'] = $avgProfitRate;
这三个量是如何计算的?
瓶颈应该在这里
#4
问题的话按理来说肯定是出现在这几个变量的计算,所以我本地测试了一下,跑100条数据的时候耗时是 6.9323971271515,这性能也不想说了,代码是前人写的。也就是1000条需要70秒,10000条需要1个小时这样 4个线程的话也是这样计算 但是问题是 我本地测试没有问题 虽然会慢一点 线上服务器发生了一个问题 死锁 这搞得比较纠结 所以这块得急需优化一下 但是问题是
$data['sold_60'] = $sold_60;
$data['backMoney_60'] = $skuMoneybackCount;
$data['profitRate_15'] = $avgProfitRate;
这三个的计算消耗的速度性能还可以..
$data['sold_60'] = $sold_60;
$data['backMoney_60'] = $skuMoneybackCount;
$data['profitRate_15'] = $avgProfitRate;
这三个的计算消耗的速度性能还可以..
#5
提供两个方案吧
1、改为触发式的更新,不用每天都集中在同一个时间段统计。若是这个产品被读取出来显示了(不管是列表还是详情之类的,看你业务需求),并且今天还没有更新过(可在 erp_products_data 表设置一个字段来标识),就执行统计更新,最好是异步
2、改为异步并发统计,就像你设置crontab 一样,只是这是代码层上的,一个分发页面,一个执行页面,执行页面接收来自分发页面的参数,从哪里开始执行统计,可以异步发起多个执行请求(10个,20个,随你)
1、改为触发式的更新,不用每天都集中在同一个时间段统计。若是这个产品被读取出来显示了(不管是列表还是详情之类的,看你业务需求),并且今天还没有更新过(可在 erp_products_data 表设置一个字段来标识),就执行统计更新,最好是异步
2、改为异步并发统计,就像你设置crontab 一样,只是这是代码层上的,一个分发页面,一个执行页面,执行页面接收来自分发页面的参数,从哪里开始执行统计,可以异步发起多个执行请求(10个,20个,随你)
#6
这三个量在计算时只传递了简单的参数,而这三个量都与历史数据有关(都是统计值)
你不去考究他们的算法,就想当然的说 性能还可以。是很不严肃的
你不去考究他们的算法,就想当然的说 性能还可以。是很不严肃的
#7
@xuzuning
目前来看 版主的考虑是对的 这块可以改为批量更改就能解决
@jam00这位朋友的也是很好的 监听触发 异步队列执行,可以代码上来监听,也可以写个触发器监听。业务上来看,这块触发的地方有点多,代码监听可能不太适合,触发器监听应该会比较好 不过这块最好不写触发器 所以我考虑版主的批量进行试一下 性能应该会好很多
目前来看 版主的考虑是对的 这块可以改为批量更改就能解决
@jam00这位朋友的也是很好的 监听触发 异步队列执行,可以代码上来监听,也可以写个触发器监听。业务上来看,这块触发的地方有点多,代码监听可能不太适合,触发器监听应该会比较好 不过这块最好不写触发器 所以我考虑版主的批量进行试一下 性能应该会好很多
#8
1.如果数据量很大, 可以用计划任务去跑,如果实时性要求不是很高。
2.开启多个线程去处理数据,这样在速度上有提高。
2.开启多个线程去处理数据,这样在速度上有提高。
#9
目前是crontab开了4个线程跑的
#10
如果没有大量 I/O 操作,多线程要比单线程还慢!
#11
1.看看查询的,对查询字段都加了索引
2.更新可以把多条更新语句先保存,然后批量更新,这样可以减少锁表开锁时间
3.相同的product估计数据是一样的,可以先把所有product放入cache,使用时直接从cache读取,减少连接数据库操作。
4.更新涉及锁表,所以多线程都是需要等待的。
2.更新可以把多条更新语句先保存,然后批量更新,这样可以减少锁表开锁时间
3.相同的product估计数据是一样的,可以先把所有product放入cache,使用时直接从cache读取,减少连接数据库操作。
4.更新涉及锁表,所以多线程都是需要等待的。
#12
触发式好一些,有人看的时候再计算,今天计算过的不用再次计算
但如果你想搞排名就不行了,把6W多条数据拆开来一点点处理
但如果你想搞排名就不行了,把6W多条数据拆开来一点点处理
#1
目前我是把他拆分开 跑4次 性能还是不行
#2
#3
$data['sold_60'] = $sold_60;
$data['backMoney_60'] = $skuMoneybackCount;
$data['profitRate_15'] = $avgProfitRate;
这三个量是如何计算的?
瓶颈应该在这里
$data['backMoney_60'] = $skuMoneybackCount;
$data['profitRate_15'] = $avgProfitRate;
这三个量是如何计算的?
瓶颈应该在这里
#4
问题的话按理来说肯定是出现在这几个变量的计算,所以我本地测试了一下,跑100条数据的时候耗时是 6.9323971271515,这性能也不想说了,代码是前人写的。也就是1000条需要70秒,10000条需要1个小时这样 4个线程的话也是这样计算 但是问题是 我本地测试没有问题 虽然会慢一点 线上服务器发生了一个问题 死锁 这搞得比较纠结 所以这块得急需优化一下 但是问题是
$data['sold_60'] = $sold_60;
$data['backMoney_60'] = $skuMoneybackCount;
$data['profitRate_15'] = $avgProfitRate;
这三个的计算消耗的速度性能还可以..
$data['sold_60'] = $sold_60;
$data['backMoney_60'] = $skuMoneybackCount;
$data['profitRate_15'] = $avgProfitRate;
这三个的计算消耗的速度性能还可以..
#5
提供两个方案吧
1、改为触发式的更新,不用每天都集中在同一个时间段统计。若是这个产品被读取出来显示了(不管是列表还是详情之类的,看你业务需求),并且今天还没有更新过(可在 erp_products_data 表设置一个字段来标识),就执行统计更新,最好是异步
2、改为异步并发统计,就像你设置crontab 一样,只是这是代码层上的,一个分发页面,一个执行页面,执行页面接收来自分发页面的参数,从哪里开始执行统计,可以异步发起多个执行请求(10个,20个,随你)
1、改为触发式的更新,不用每天都集中在同一个时间段统计。若是这个产品被读取出来显示了(不管是列表还是详情之类的,看你业务需求),并且今天还没有更新过(可在 erp_products_data 表设置一个字段来标识),就执行统计更新,最好是异步
2、改为异步并发统计,就像你设置crontab 一样,只是这是代码层上的,一个分发页面,一个执行页面,执行页面接收来自分发页面的参数,从哪里开始执行统计,可以异步发起多个执行请求(10个,20个,随你)
#6
这三个量在计算时只传递了简单的参数,而这三个量都与历史数据有关(都是统计值)
你不去考究他们的算法,就想当然的说 性能还可以。是很不严肃的
你不去考究他们的算法,就想当然的说 性能还可以。是很不严肃的
#7
@xuzuning
目前来看 版主的考虑是对的 这块可以改为批量更改就能解决
@jam00这位朋友的也是很好的 监听触发 异步队列执行,可以代码上来监听,也可以写个触发器监听。业务上来看,这块触发的地方有点多,代码监听可能不太适合,触发器监听应该会比较好 不过这块最好不写触发器 所以我考虑版主的批量进行试一下 性能应该会好很多
目前来看 版主的考虑是对的 这块可以改为批量更改就能解决
@jam00这位朋友的也是很好的 监听触发 异步队列执行,可以代码上来监听,也可以写个触发器监听。业务上来看,这块触发的地方有点多,代码监听可能不太适合,触发器监听应该会比较好 不过这块最好不写触发器 所以我考虑版主的批量进行试一下 性能应该会好很多
#8
1.如果数据量很大, 可以用计划任务去跑,如果实时性要求不是很高。
2.开启多个线程去处理数据,这样在速度上有提高。
2.开启多个线程去处理数据,这样在速度上有提高。
#9
目前是crontab开了4个线程跑的
#10
如果没有大量 I/O 操作,多线程要比单线程还慢!
#11
1.看看查询的,对查询字段都加了索引
2.更新可以把多条更新语句先保存,然后批量更新,这样可以减少锁表开锁时间
3.相同的product估计数据是一样的,可以先把所有product放入cache,使用时直接从cache读取,减少连接数据库操作。
4.更新涉及锁表,所以多线程都是需要等待的。
2.更新可以把多条更新语句先保存,然后批量更新,这样可以减少锁表开锁时间
3.相同的product估计数据是一样的,可以先把所有product放入cache,使用时直接从cache读取,减少连接数据库操作。
4.更新涉及锁表,所以多线程都是需要等待的。
#12
触发式好一些,有人看的时候再计算,今天计算过的不用再次计算
但如果你想搞排名就不行了,把6W多条数据拆开来一点点处理
但如果你想搞排名就不行了,把6W多条数据拆开来一点点处理