项目中经常碰到一些慢 sql,sql 本身没有继续优化的空间,该使用的索引也都用上了。想要继续优化,就要考虑每次分块处理,也就是把原先大的结果集分割成一个个的小块,类似于 Laravel
的 chunk
方法。
这里基于我司的 PHP 框架写了个简单的使用方式,通过传入 sql 的方式把 sql 中的占位符 ? 号替换为 where in 条件中的子集。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 trait getDataInChunkTrait { public function getDataInChunk (array $list , string $sql , int $size = 500 ): array { $result = []; $model = M ('' ); foreach (array_chunk ($list , $size ) as $sub_list ) { $sub_str = implode (',' , $sub_list ); $run_sql = str_replace ('?' , $sub_str , $sql ); $result = array_merge ($result , $model ->select ($run_sql ) ?: []); } return $result ; } }
可以这么使用
1 2 3 4 5 6 7 $sql = "SELECT order_id, max(create_time) as running_time FROM order_operate WHERE order_id IN (?) AND after_status = 4 GROUP BY order_id" ;$orders = $this ->getDataInChunk ($orders , $sql , 200 );