当前位置: 首页 > news >正文

美食网站中饮食资讯该怎么做/百度seo收录软件

美食网站中饮食资讯该怎么做,百度seo收录软件,怎么样制作网站,园林景观设计公司年度运营方案接触php一年左右,系统初写的时候我没有过多的考虑性能问题,能简则简,能用一句sql解决的问题绝不多写一个标点符号的代码,于是为更新汇总子订单成本写了这个函数/*** 更新子订单成本* param array $tidList 可选 要更新的tid 不传参…

接触php一年左右,系统初写的时候我没有过多的考虑性能问题,能简则简,能用一句sql解决的问题绝不多写一个标点符号的代码,于是为更新汇总子订单成本写了这个函数

/**

* 更新子订单成本

* @param array $tidList 可选 要更新的tid 不传参数全量更新

* @return int

*/

public function updateOrderCost(array $tidList = [])

{

$sql = "UPDATE taobao_trade_order a SET a.cost = IFNULL((SELECT SUM(cost) FROM taobao_sku_modify WHERE tid = a.tid AND oid = a.oid AND status = 1),0)";

if (count($tidList)) {

$tid = implode(',', $tidList);

$sql .= " WHERE tid in ({$tid})";

}

return DB::SlimPDO()->exec($sql);

}

使用中因为$tidList一直都是有传参进行部分更新,每次更新条目最多不超过10条,并没察觉到有什么效率问题。

然后今天偶然来个空值全量更新,好啦,瞬间mysql锁死,整个系统处于瘫痪状态,等了足足差不多 5分钟 才把这段语句执行完。

taobao_trade_order只有不到3000条数据,taobao_sku_modify也就6000多而已,这么点数据量让系统锁死5分钟,这段代码亟待优化了。

出于我能简就简的习惯,我一上来依然是

从sql语句上着手,看看是否有提升空间。

tid,oid,status几个关键字段已经设置索引。

然后观察到这段代码执行的时候每次SET cost的时候都要执行后面的SELECT 语句,等于要执行2000多次SELECT ,我要是把这段SELECT的数据建一个临时表,然后update从这个临时表里面读数据再更新如何呢?

可是很快发现这个创建临时表的语句我 写不出来.....

同系统下另一个函数有这样的一个sql语句

UPDATE taobao_trade a SET a.refund_fee = (SELECT SUM(refund_fee) FROM taobao_trade_order WHERE tid = a.tid) //45s

这条语句的表现比上面那个略好,嗯....主表 taobao_trade 1800条 子表 taobao_trade_order 不到3000条的数据,执行一次 45s

这个条件简单 我先拿这条语句创建临时表并更新

CREATE TEMPORARY TABLE tmp_table (

SELECT tid, SUM(refund_fee) AS refund_fee FROM taobao_trade_order GROUP BY tid

) //创建临时表 0.02s

UPDATE taobao_trade a SET a.refund_fee = (SELECT refund_fee FROM tmp_table WHERE tid = a.tid) //执行更新 14.22s

好嘛,确实有用,从45s升级到14.22s 效率提升了3倍还多,但这效率。。。依然并卵。

于是我也不再烦恼上面那个语句怎么写CREATE TEMPORARY TABLE了,这条路不通!

不过如果有人知道这种多个字段去重,并按某个字段的字段量来汇总另一个字段怎么建表希望不吝赐教。

既然mysql上面没有好的解决办法,只能考虑从

php代码上优化

通俗的讲,这段要实现的是通过库存变更表taobao_sku_modify计算每个子订单成本,然后赋值到子订单表相关联的子订单上,通过tid和oid2个字段判断关联性。

我首先把代码改成这样

public function updateOrderCost(array $tidList = [])

{

$search = DB::SlimPDO()

->select(['tid', 'oid', 'cost'])

->from('taobao_sku_modify')

->where('status', '=', 1)

->where('oid', '<>', '');

if (count($tidList)) {

$search->whereIn('tid', $tidList);

}

$list = $search->orderBy('tid')->execute()->fetchAll();

function update($result)

{

DB::SlimPDO()

->update(['cost' => $result['cost']])

->table('taobao_trade_order')

->where('tid', '=', $result['tid'])

->where('oid', '=', $result['oid'])

->execute();

}

$result = [

'tid' => '',

'oid' => '',

'cost' => 0

];

foreach ($list as $item) {

if ($result['tid'] !== $item['tid']) {

if ($result['tid']) {

update($result);

}

$result = [

'tid' => $item['tid'],

'oid' => $item['oid'],

'cost' => 0

];

} elseif ($result['oid'] !== $item['oid']) {

update($result);

$result['oid'] = $item['oid'];

$result['cost'] = 0;

}

$result['cost'] += $item['cost'];

}

update($result);

}

这就是我更愿意一句sql解决的原因,与原函数做一样的事情,一句sql变成了这么长一段函数,我已尽量简洁,但是看起来还是没有sql语句直观,算了,执行看看效率。

执行结果是卓有成效的,因为这次系统只卡了 86.977087020874s

从5分钟提升到差不多一分半钟,效率提升了3倍,我想如果把数据提取成临时表进行更新也差不多是这个效率了,因为它们逻辑一样。

这种效率显然不是我想要的,而且我也很快找出了问题,update函数执行了3000多次,但是执行结果都是0,也就是之前执行更新cost数据与重新计算的cost一样,并没有数据被更新,我是否可以在php层判断结果是否一致,而避免不断的做update呢,当然可以,我把函数上半部分的代码改成这样

public function updateOrderCost(array $tidList = [])

{

$search = DB::SlimPDO()

->select(['tid', 'oid', 'cost'])

->from('taobao_sku_modify')

->where('status', '=', 1)

->where('oid', '<>', '');

$sql = "SELECT cost, tid, oid FROM taobao_trade_order"; //新增

if (count($tidList)) {

$search->whereIn('tid', $tidList);

$tid = implode(',', $tidList);

$sql .= " WHERE tid in ({$tid})"; //新增

}

$list = $search->orderBy('tid')->execute()->fetchAll();

$orderList = DB::SlimPDO()->query($sql)->fetchAll(); //新增

$_update = function ($result) use ($orderList) //优化

{

if (!Func::array_find($orderList, $result)) { //通过判断orderList中是否有与result键名键值一致的数组

DB::SlimPDO()

->update(['cost' => $result['cost']])

->table('taobao_trade_order')

->where('tid', '=', $result['tid'])

->where('oid', '=', $result['oid'])

->execute();

}

};

执行看看,好的,有效,这次的执行时间是 29.660382032394s

还能更快吗,这效率依然不够啊,这段代码的主要时间浪费在Func::array_find的查询上,这是一个自定义的函数,用在判断参数一的二维数组是否有包含参数二的所有同键名键值的数组,参数二可以是闭包函数也可以是字符串。

我认为Func::array_find已经没有提升空间,只能找别的方法来替代,第一个想到的是in_array,可是in_array不能筛二维数组,那我把源数据直接改成一维的吧,反正只有三个字段

为了得到一维数组我把

$orderList = DB::SlimPDO()->query($sql)->fetchAll();

改成

$orderList = array_map(function ($item) {

return $item['tid'] . $item['oid'] . $item['cost'];

}, DB::SlimPDO()->query($sql)->fetchAll());

然后更新了update函数的判断方式

$_update = function ($result) use ($orderList)

{

$test = $result['tid'] . $result['oid'] . $result['cost'];

if (!in_array($test, $orderList)) {

DB::SlimPDO()

->update(['cost' => $result['cost']])

->table('taobao_trade_order')

->where('tid', '=', $result['tid'])

->where('oid', '=', $result['oid'])

->execute();

}

};

这次我信心满满,因为已经用了系统内置的函数,应该没什么大问题了。

按下执行键的时候我快斯巴达了,还是卡住了,这次的执行时间是 30.925987958908s

跟自定义的Func::array_find判断函数比 in_array并没有带来性能的提升。

怎么办,我已经得到了差不多3000条数据的一维数组$orderList ,要让它进行差不多3000次的重复值判断,要怎么样才能把性能提升到可以接受的地步?

我搜罗了一番,找到了 iseet() 和 array_key_exists()这两个函数,并最终选则了isset

isset只能判断键名 这个好办,用array_flip把我的$orderList键值互转一下

$orderList = array_flip(array_map(function ($item) {

return $item['tid'] . $item['oid'] . $item['cost'];

}, DB::SlimPDO()->query($sql)->fetchAll()));

然后把判断语句

if (!in_array($test, $orderList))

改成

if (!isset($orderList[$test]))

执行,一颗心放下了,最终执行时间 0.45861196517944s

终于到了可以接受的程度,这是最终的函数代码,以我目前技术能想到的最优方案

/**

* 更新子订单成本

* @param array $tidList 可选 要更新的tid 不传参数全量更新

*/

public function updateOrderCost(array $tidList = [])

{

$search = DB::SlimPDO()

->select(['tid', 'oid', 'cost'])

->from('taobao_sku_modify')

->where('status', '=', 1)

->where('oid', '<>', '');

$sql = "SELECT cost, tid, oid FROM taobao_trade_order";

if (count($tidList)) {

$search->whereIn('tid', $tidList);

$tid = implode(',', $tidList);

$sql .= " WHERE tid in ({$tid})";

}

$list = $search->orderBy('tid')->execute()->fetchAll();

$orderList = array_flip(array_map(function ($item) {

return $item['tid'] . $item['oid'] . $item['cost'];

}, DB::SlimPDO()->query($sql)->fetchAll()));

$Update = function ($result) use ($orderList) {

$test = $result['tid'] . $result['oid'] . $result['cost'];

if (!isset($orderList[$test])) {

DB::SlimPDO()

->update(['cost' => $result['cost']])

->table('taobao_trade_order')

->where('tid', '=', $result['tid'])

->where('oid', '=', $result['oid'])

->execute();

}

};

$result = [

'tid' => '',

'oid' => '',

'cost' => 0

];

foreach ($list as $item) {

if ($result['tid'] !== $item['tid']) {

if ($result['tid']) {

$Update($result);

}

$result = [

'tid' => $item['tid'],

'oid' => $item['oid'],

'cost' => 0

];

} elseif ($result['oid'] !== $item['oid']) {

$Update($result);

$result['oid'] = $item['oid'];

$result['cost'] = 0;

}

$result['cost'] += $item['cost'];

}

$Update($result);

}

http://www.lbrq.cn/news/736867.html

相关文章:

  • 建设网站的公司兴田德润怎么联系/中山疫情最新消息
  • 怎么样在网上建设网站挣钱/名片seo什么意思
  • 肇庆网站建设公司/百度风云榜小说榜排名
  • 在58同城做网站有生意吗/网络推广员为什么做不长
  • 重庆好的seo平台/关键词排名优化江苏的团队
  • aspnet网站开发作业/好视通视频会议app下载安装
  • 网络培训网站/营销推广的平台
  • 网页版抖音入口官网/台州百度推广优化
  • 做的视频发到哪个网站好/2023半夜免费b站推广
  • 长春网站建设工作室/百度seo如何做
  • 动态网站建设与规划/seo优化排名价格
  • 做一个简单网站/推广软件排行榜前十名
  • 常州做网站公司哪家好/百度收录查询
  • 建设网站需要了解些什么/举出最新的网络营销的案例
  • 英文网站备案/2023新闻摘抄大全
  • 网站建设 收费明细/seo全称
  • 南宁市疫情最新情况详细地址/南宁seo推广
  • 网站优化方案ppt/网络营销推广合作
  • 自己网站上做淘宝搜索/站长统计app软件
  • 那家公司做网站比较好/十八未成年禁用免费app
  • 大连网络推广宣传/杭州seo靠谱
  • 为什么要用模板建站/营销推广文案
  • 上海专业网站建设服/如何做运营推广
  • 企业网站维护更新/长尾词和关键词的区别
  • 开发网站需要哪些技术/免费创建网站平台
  • 技术支持 优府网络太原网站建设/广告加盟
  • wordpress插件用户权限/东莞seo网站优化排名
  • 苏州网站设计公司/2023疫情最新消息今天
  • 青岛百度快速排名优化/什么是seo优化
  • 家用电脑和宽带做网站/发布友情链接
  • 深度卷积神经网络AlexNet
  • imx6ull-驱动开发篇30——Linux 非阻塞IO实验
  • C++进阶-----C++11
  • Java并发容器详解
  • 【C++】--指针与引用深入解析和对比
  • 【verge3d】如何在项目里调用接口