这期内容当中小编将会给大家带来有关怎样进行ThinkPHP中网站性能优化研究,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。
轻易不要用多表查询,如下代码以及模拟数据测试结果能让你清晰地认识到多表查询,join,left join,inner join的可怕之处,能不用就不要用
/** * 获取持有偶像币总估值 * @param $uid * @return mixed * @author zzl zzl@ourstu.com * 时间:2019.06.18 */ public function getHasCoinExpect($uid){ $tag='_User_total_tnk_'.$uid; $total=S($tag); if($total===false){ $total=0; //获取持有偶像币估值 $page=1;//分页查询,防止某个用户拥有太多种偶像币,如管理员 $row=5000; do{ //测试idol_coin_has表40W条记录,用户10W条记录,单次循环耗时0.1s左右 $idol_has_list=$idol_uids=$idol_price_list=array(); $price=$has_num=0; $idol_has_list=$this->where(array('uid'=>$uid,'has_num'=>array('gt',0)))->page($page,$row)->order('has_num desc,idol_uid asc')->getField('idol_uid,has_num'); $idol_uids=array_keys($idol_has_list); $idol_price_list=D('Idol/Idol')->where(array('uid'=>array('in',$idol_uids),'single_price'=>array('gt',0),'status'=>1))->getField('id,uid,single_price');//这里增加single_price字段,初始化时为0,有交易时改变 foreach ($idol_price_list as $vo){ $price=$vo['single_price']; $has_num=$idol_has_list[$vo['uid']]; $total=bc_add(bc_mul($has_num,$price,4),$total,4); } unset($vo); $page++; }while(count($idol_has_list)==$row); S($tag,$total,60); //测试idol_coin_has表40W条记录,要查询用户的偶像币持有条数有10W条记录,总耗时1.5~2.5s之间 } return $total; //如下注释方案,采用inner join方式 测试idol_coin_has表40W条记录,用户10W条记录,直接崩溃,无响应,所以舍弃该方案 /*if(1||$total===false){ $total=0; //获取持有偶像币估值 $page=1;//分页查询,防止某个用户拥有太多种偶像币,如管理员 $row=500; G('d'); $sql="select table1.uid,table1.idol_uid,table1.has_num,table2.single_price from __PREFIX__idol_coin_has as table1 inner join __PREFIX__idol_info as table2 on table1.uid={$uid} AND table1.has_num>0 AND table2.single_price>0 AND table1.idol_uid = table2.uid ORDER BY table1.has_num desc,table2.single_price desc "; do{ G('a'); $sql_do=$sql."limit ".($page-1)*$row.",".$row; $list=$this->query($sql_do); foreach ($list as $val){ $total=bc_add(bc_mul($val['has_num'],$val['single_price'],4),$total,4); } unset($val); dump($total); dump($page); $page++; G('b'); dump(G('a','b')); }while(count($list)==$row); dump('e'); dump(G('d','e'));exit; S($tag,$total,60); }*/ }
对于大批量的操作,千万不要在foreach中出现sql查询,如下代码:
一条一条save的方案,每条操作都要0.01s左右,10W条的话,需要100s,是当前方案耗时的10倍,所以这里采用删除老记录,批量新增新记录的方式操作
/** * 重新计算排名 * @return boolean * @author 郑钟良(zzl@ourstu.com) * @date slf */ private function _calculateRanking() { $heatModel=D('idol_heat'); $map['status']=1; $order='heat desc,uid asc'; $page=1; $row=5000; $rank=1; $this->startTrans(); do{ //用9W条数据测试,如果每条都需要改,单次循环需要0.55s,全部执行完需要11s左右 //用9W条数据测试,如果有1W条数据需要改,单次循环需要0.15s,全部执行完需要3s左右 //实际使用环境中,每次改变不会超过十分之一,而且总用户量很难达到10W,所以,该方案可行 $heatList=$heatModel->where($map)->order($order)->page($page,$row)->select(); $rank_list=$del_ids=array(); foreach ($heatList as $val){ if($val['last_rank']!=$val['rank']||$val['change_rank']!=$rank-$val['rank']||$val['rank']!=$rank){ $val['last_rank']=$val['rank']; $val['change_rank']=$rank-$val['rank']; $val['rank']=$rank; $rank_list[]=$val; $del_ids[]=$val['uid']; } $rank++; } unset($val); if(count($del_ids)){ //一条一条save的方案,每条操作都要0.01s左右,10W条的话,需要100s,是当前方案耗时的10倍,所以这里采用删除老记录,批量新增新记录的方式操作 $res=$heatModel->where(array('uid'=>array('in',$del_ids)))->delete(); $res1=$heatModel->addAll($rank_list); }else{ $res=1; $res1=1; } if(!$res||!$res1){ break; } $page++; }while(count($heatList)==$row); if($res&&$res1){ if($this->commit()){ return true; } }else{ $this->rollback(); } return false; }
上述就是小编为大家分享的怎样进行ThinkPHP中网站性能优化研究了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。