优化基于以下几个原则:
1、尽量以小结果集驱动大结果集(和mysql中join类似);
2、尽量少在循环中执行sql操作,如果一定要执行sql,尽量批量执行;
3、尽量减少逻辑性代码和调用外部方法,如必要,尽量在在小结果集上处理的;
4、实际应用中发现循环嵌套使用的数据大部分一样,只有小部分不同,果断提取,外部处理;
场景1:
1 <?php 2 3 $data = array(); 4 //参数 5 6 $kid = []; //数组长度大于300 7 $dataarray = []; //数组长度大于50 8 9 foreach ($dataarray as $k=>$v){ 10 11 $starttime = 0; 12 $endtime = 0; 13 $timearr[$starttime.$endtime]['rid'][] = $k; 14 $data = array(); 15 $i=0; 16 foreach ($kid as $kk){ 17 18 $data[$i]['k'] = $kk; 19 $data[$i]['m'] = $kk; 20 $data[$i]['n'] = $kk; 21 //必要的赋值操作 22 //... 23 24 //各种逻辑判断,并且赋值使用的是上一级嵌套中的变量 25 if (!empty($v['a'])) 26 $data[$i]['a'] = $v['a']; 27 if (!empty($v['a'])) 28 $data[$i]['a'] = $v['a'].",".$v['a']; 29 30 if (!empty($v['a'])) 31 $data[$i]['a'] = $v['a']; 32 if (!empty($v['a'])) 33 $data[$i]['a'] = $v['a'].",".$v['a']; 34 35 if (!empty($v['a'])) 36 $data[$i]['a'] = $v['a']; 37 if (!empty($v['a'])) 38 $data[$i]['a'] = $v['a'].",".$v['a']; 39 $i++; 40 } 41 //插入数据 42 $allin = $this->model->table('pp')->addALL($data); 43 } 44 exit;
以上代码实际使用中执行时长大概 20s
优化后如下,把必要的逻辑操作,又涉及到上一层循环变量,提取出来,不要放在大结果集中处理,执行时长大概 3秒
<?php //参数 $kid = []; $dataarray = []; foreach ($dataarray as $k=>$v){ if (!empty($v['a'])) $a = $v['a']; if (!empty($v['a'])) $a = $v['a'].",".$v['a']; if (!empty($v['a'])) $a = $v['a']; if (!empty($v['a'])) $a = $v['a'].",".$v['a']; if (!empty($v['a'])) $a = $v['a']; if (!empty($v['a'])) $a = $v['a'].",".$v['a']; $data = []; foreach ($kid as $mm=>$kk){ $data[$mm]['k'] = $kk; $data[$mm]['m'] = $kk; $data[$mm]['n'] = $kk; //必要的赋值操作 //... $data[$mm]['a'] = $a; $data[$mm]['a'] = $a; $data[$mm]['a'] = $a; $data[$mm]['a'] = $a; } //插入数据 $allin = $this->model->table('pp')->addALL($data); } exit;
场景2:
优化前,执行时间80秒,其中循环时间 62,数据库操作时间 18秒
1 <?php 2 3 4 //参数 5 6 $kid = [];//长度大于300 7 8 9 10 $dataarray = []; //长度大于50 11 $stimearr = []; 12 $etimearr = []; 13 14 $countTime = count($stimearr); //长度大于 5 15 16 for ($a = 0;$a < $countTime;$a++) { //注意,后面两层嵌套中,除了时间不一样,其他完全一样 17 18 $stime = strtotime($stimearr[$a]); 19 $etime = strtotime($etimearr[$a]); 20 21 22 foreach ($kid as $kk) { // 大结果集 23 $data = array(); 24 $i = 0; 25 foreach ($dataarray as $k => $v) { //小结果集合 26 27 $data[$i]['a'] = $kk; 28 $data[$i]['a'] = intval($k); 29 $data[$i]['a'] = $v['a']; 30 $data[$i]['a'] = $v['a']; 31 $data[$i]['stime'] = $stime; 32 $data[$i]['etime'] = $etime; 33 34 if ($a) { 35 $data[$i]['a'] = $k; 36 $data[$i]['a'] = $k; 37 } 38 if ($a) { 39 $data[$i]['a'] = $k; 40 $data[$i]['a'] = $k; 41 } 42 $i++; 43 } 44 //插入数据 45 $allin = $this->model->table('pp')->addAll($data); 46 } 47 } 48 exit;
优化后
<?php //参数 $kid = [];//长度大于300 $dataarray = []; //长度大于50 $stimearr = []; $etimearr = []; $countTime = count($stimearr); //长度大于 5 $i = 0; $data = []; //提取数据保存 foreach ($dataarray as $k=>$v){ //小结果集 $a = 'xxx'; //逻辑处理 $a = 'xxx'; //逻辑处理 $a = 'xxx'; //逻辑处理 $a = 'xxx'; //逻辑处理 foreach ($kid as $mm=>$kk){ //大结果集合 $data[$i][$mm]['a'] = $kk; $data[$i][$mm]['a'] = intval($k); $data[$i][$mm]['a'] = $v['a']; $data[$i][$mm]['a'] = $v['a']; $data[$i][$mm]['a'] = $a; $data[$i][$mm]['a'] = $a; $data[$i][$mm]['a'] = $a; } $i ++; } for ($b = 0;$b < $countTime;$a++) { $stime = strtotime($stimearr[$b]); $etime = strtotime($etimearr[$b]); foreach ($data as $k=>$v){ foreach ($v as $kk=>$vv){ $data[$k][$kk] = array_merge($data[$k][$kk],['starttime'=>$stime,'endtime'=>$etime]); } //插入数据 $allin = $this->model->table('pp')->addALL($data[$k]); } }