接口信息:安装量汇总 数据量:18w
前言: 旧接口优化,原接口采用原生sql.进行迭代升级优化。
指标:响应效率 功能优化 代码升级
原接口:
单日汇总统计1.69s
优化后 单日汇总统计.5s
30日汇总统计5.59s
优化后 30日汇总统计5.59s
优化内容
第一版
$fields = "count(*) as setup_count,p.pid,p.addtime as date_name,s.name as p_name,t.title as type_title,s.os,s.panel_pro,ifnull(pl.ps,s.ps) as ps,ifnull(pl.name,s.title) as name,round(ifnull(pl.price,0),2) as price,ifnull(pl.id,p.pid) as product_id";
$sort = ['setup_count'=>'desc'];
$with = [];
$where =function (Query $query) use($params){
if ($params['price_type'] =='1'){
$query->whereNotNull('pl.id');
}
if ($params['price_type'] =='2'){
$query->whereNull('pl.id');
}
$query->where('p.addtime','>=',$params['from_date']);
$query->where('p.addtime','<=',$params['end_date']);
};
$list = SoftList::alias('s')
->join('wz_soft_type t','t.id=s.type')
->join('wz_product_list pl','pl.id=s.pid','left')
->join('wz_plugin_total p','p.pid = s.id')
->field($fields)
->where($where)
->page($this->page,$this->pageSize)
->group('p.pid')
->order($sort)
->select();
总结
wz_plugin_total索引addtime_pid字段addtime和pid返回的行数4000多,查询会处理大量数据行,这可能导致性能下降,连接行数过高整体查询性能仍会受影响。所以这个方案再日期范围小的时候还能适用,但是范围一旦扩大就不适用。直接在数据库层执行所有的操作,理论上减少了数据传输量和 PHP 层的处理。但由于多表 JOIN 操作可能涉及大量数据,索引的利用率和查询优化策略至关重要。如果索引不当或涉及的数据量过大,查询性能可能会显著下降,导致卡顿或超时。
第二版
$list = PluginTotal::where($where)
->field("count(*) as setup_count,pid,addtime as date_name,pid as product_id")
->group('pid')
->order($sort)
->select();//199
$SoftList = SoftList::alias('s')
->join('wz_soft_type t','t.id=s.type')
->column('s.title as name,s.os,s.panel_pro,t.title,price','s.id');
$data =[];
foreach ($list as $k=>&$v){
if (isset($SoftList[$v['pid']])){
$info=$v;
if ($params['price_type'] =='1'){
if ($SoftList[$v['pid']]['price'] <= 0){
continue;
}
}
if ($params['price_type'] =='2'){
if ($SoftList[$v['pid']]['price'] > 0){
continue;
}
}
$info['name']=$SoftList[$v['pid']]['name'];
$info['os']=$SoftList[$v['pid']]['os'];
$info['panel_pro']=$SoftList[$v['pid']]['panel_pro'];
$info['type_title']=$SoftList[$v['pid']]['title'];
$info['price']=$SoftList[$v['pid']]['price'];
$info['date_name']=date('Y-m-d H:i:s',$params['from_date']).'-'.date('Y-m-d H:i:s',$params['end_date']);
$data[]=$info;
}
}
//重新排序
array_multisort(array_column($data, 'setup_count'), SORT_DESC, $data);
return jsonSuccess('获取成功',$data);
总结 独立查询后再聚合,单表查询优化最大限度的。两次查询分别处理数据,然后在 PHP 层进行数据合并。减少了数据库的负担。
汇总总结
-
聚合查询 适用于小数据量、明确索引、查询优化良好的场景。
-
独立查询后聚合 适用于大数据量、多表查询可能导致性能瓶颈的场景。通过减少单次查询的复杂度,分步骤完成整个数据获取与处理过程。 更多优化想法 问了公司大佬提出了一个外键索引的方式,这个方式我还没试过。有空再去试试 大家还有什么优秀的方案或者方式也可以提出来,在改进中提升自己。