PHP优化教程之解决嵌套问题

在开发过程中,我们经常遇到一对多的场景,

例如:查询订单列表,并且展示订单详情商品、数量数据

思路0:传统做法

a. 查询订单列表

b. 遍历订单详情

	$orderList = select * from order where xx;
	foreach($orderList as $orderItem) {
		$orderItem->detailList = select * from order_detail where order_id = $orderItem->id;
	}

分析:查询SQL次数为:N+1(N为订单个数),这样频繁请求数据库,影响效率

优化:减少频繁请求数据库

思路1:

a. 查询订单列表后,利用in查出所有订单详情

b. 通过(订单表id => 订单详情表order_id)遍历匹配数据

	$orderList = select * from order where xx;
	$orderId = array_pluck($orderList, 'id'); // Laravel内置数组辅助函数
	$orderDetailList = select * from order_detail where order_id IN $orderId;
	foreach($orderList as $orderItem) {
		$detailListTemp = [];
		foreach($orderDetailList as $orderDetailItem) {
			if ($orderItem->id == $orderDetailItem->order_id) {
				$detailListTemp[] = $orderDetailItem;
			}
		}
		$orderItem->detailList = $detailListTemp;
	}

分析:降低查询后,但2层遍历,复杂度较高,数量过大容易内存溢出

优化:降低复杂度

思路2:

a. 查询订单列表后,利用in查出所有订单详情

b. 订单详情列表转换成以订单ID为索引,用isset来匹配订单的详情

	$orderList = select * from order where xx;
	$orderId = array_pluck($orderList, 'id'); // Laravel内置数组辅助函数
	$orderDetailList = select * from order_detail where order_id IN $orderId;

	// 将订单详情转换成以订单ID为索引【方式1】
	$orderDetailList = arrayGroup($orderDetailList, 'order_id');
	// 或:将订单详情转换成以订单ID为索引【方式2:如果为一对一,可以用array_column】
	// $orderList = array_column($orderDetailList, null, 'order_id'); 

	foreach($orderList as $orderItem) {
		$orderItem->detailList = $orderDetailList[$orderItem->id] ?? [];
	}

	// 根据KEY数组分组
	function arrayGroup($list, $key) {
	 $newList = [];
	 foreach ($list as $item) {
	  $newList[$item[$key]][] = $item;
	 }
	 return $newList;
	}

总结

到此这篇关于PHP优化教程之解决嵌套问题的文章就介绍到这了,更多相关PHP解决嵌套问题内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • PHP函数用法详解【初始化、嵌套、内置函数等】

    本文实例讲述了PHP函数用法.分享给大家供大家参考,具体如下: 初始函数 函数:封装一段用于完成特定功能的代码. 通俗理解函数:可以完成魔鬼工作的代码块,就像积木一样,可以反复使用,在使用的时候,拿来即用. 函数定义:1)内置函数(字符串操作函数.数组操作函数)2)自定义函数 函数的基本语法格式 function 函数名([参数1.参数2,......]){ 函数体...... } 函数的定义由一下四部分组成: 关键字function function: 在声明函数时必须使用的关键字: 函数名f

  • php无限级评论嵌套实现代码

    我在设计BB的过程中,也一直在思考是否可以不通过递归来实现无限级分类的结构展现和父子结构查找,因为如果不对这里的算法进行优化后果可能是致命的!试想一下,一篇文章如果评论数为300,按正常的递归算法,至少就得查询数据库301次,而且还是在没有任何嵌套的情况下,如果有过一两级嵌套或者评论数过1000,那数据库不是直接宕掉? 而实际上,PHP强大的数组处理能力已经能帮助我们快速方便的解决这个问题.下图为一个无限级分类的 数据库结构: IDparentID newsID commts 108文章ID为8

  • PHP 修复未正常关闭的HTML标签实现代码(支持嵌套和就近闭合)

    fixHtmlTag version 0.2 这个版本解决了上次遗留的问题,即就近闭合和嵌套闭合问题.具体可以看代码的注释. 复制代码 代码如下: <?php /** * fixHtmlTag * * HTML标签修复函数,此函数可以修复未正确闭合的 HTML 标签 * * 由于不确定性因素太多,暂时提供两种模式"嵌套闭合模式"和 * "就近闭合模式",应该够用了. * * 这两种模式是我为了解释清楚此函数的实现而创造的两个名词, * 只需明白什么意思就行.

  • PHP中的函数嵌套层数限制分析

    函数嵌套,这个名字有点纠结,也许不太好理解.一个比较常见的函数嵌套特例:递归函数,即函数自己嵌套自己. 一直以为在PHP中不能有太多的函数嵌套,这是因为在以前某些时候不小心用到了递归,在递归的深度达到100时, 即函数嵌套的层数达到100时,程序会报一个 Fatal error.如下示例: 复制代码 代码如下: function rt() { static $i; echo $i++, '<br />'; rt(); } rt(); die(); 在我的win7 + php5.3的环境下报错如

  • PHP中实现MySQL嵌套事务的两种解决方案

    一.问题起源 在MySQL的官方文档中有明确的说明不支持嵌套事务: 复制代码 代码如下: Transactions cannot be nested. This is a consequence of the implicit commit performed for any current transaction when you issue a START TRANSACTION statement or one of its synonyms. 但是在我们开发一个复杂的系统时难免会无意中在

  • PHP树的代码,可以嵌套任意层

    PHP树的代码,可以嵌套任意层 <?file://建立树的主要函数,传递的参数为根节点的编号和根节点的标题function create_tree($rootid,$roottilte){  print_parent_from_rootsortid($rootid,$roottilte);}file://打印根节点div头的函数function print_parent_from_rootsortid($rootid,$roottilte){  $parent_fullname="R&qu

  • php利用嵌套数组拼接与解析json的方法

    利用嵌套数组   拼接混合json -包含对象数组 <?php // 自 PHP 5.4 起 $array = [ "status" => "0", "message" => "ok", "arr"=> [] ]; class Person { public $name; public $age; //定义一个构造方法初始化赋值 public function __construct

  • PHP嵌套输出缓冲代码实例

    PHP的输出缓存是可以嵌套的.用ob_get_level()就可以输出嵌套级别. 测试发现在cli和浏览器下输出结果不一样(PHP5.4). 手册说明如下: ob_get_level() will always return 0 inside a destructor. This happens because the garbage collection for output buffers has already done before the destructor is called 想要

  • PHP优化教程之解决嵌套问题

    在开发过程中,我们经常遇到一对多的场景, 例如:查询订单列表,并且展示订单详情商品.数量数据 思路0:传统做法 a. 查询订单列表 b. 遍历订单详情 $orderList = select * from order where xx; foreach($orderList as $orderItem) { $orderItem->detailList = select * from order_detail where order_id = $orderItem->id; } 分析:查询SQ

  • 移动开发Spring Boot外置tomcat教程及解决方法

    springboot微服务内置了tomcat,在工程目录下执行:mvn clean package,可以将项目打成jar,通过java -jar jar包名.jar启动项目. 有哪些场景需要将springboot打成war包去部署呢? 1.一个tomcat管理多个项目 2.springboot整合jsp等 解决方法: 1.<packaging>jar</packaging>中的jar改成war 2.引入依赖: <dependency> <groupid>or

  • MySQL优化教程之超大分页查询

    背景 基本上只要是做后台开发,都会接触到分页这个需求或者功能吧.基本上大家都是会用MySQL的LIMIT来处理,而且我现在负责的项目也是这样写的.但是一旦数据量起来了,其实LIMIT的效率会极其的低,这一篇文章就来讲一下LIMIT子句优化的. LIMIT优化 很多业务场景都需要用到分页这个功能,基本上都是用LIMIT来实现. 建表并且插入200万条数据: # 新建一张t5表 CREATE TABLE `t5` ( `id` int NOT NULL AUTO_INCREMENT, `name`

  • rust解决嵌套——Option类型的map和and_then方法的使用

    目录 map方法的使用 and_then方法的使用 rust基础学习历程 先提一个建议如果是通过rust官网入门的话,个人感觉<通过例子学 Rust>会比<Rust 程序设计语言>更好一些. 我这里的例子实际上也是官网上的例子,对于看一遍不太清晰的例子,我会选择自己写下来. 这篇文章假设你已经了解了关于Option类型的一些概念(实际上是rust用来处理空值的工具). map方法的使用 需求:假设我想吃一种食物,这个食物需要经过削皮.切块和煮熟这三个线性的流程,此外在这三个流程之前

  • Android 解决嵌套Fragment无法接收onCreateOptionsMenu事件的问题

    前言 嵌套的二级Fragment无法接收onCreateOptionsMenu事件的问题,设置了setHasOptionsMenu也不管用. 正文 补充说明: 如果通过缓存Fragment手动调用二级Fragment,可能会出现莫名其妙的问题,比如更多Menu不显示. 解决办法: 在一级Fragment中添加Menu,可以在一级onOptionsItemSelected中手动调用二级的此方法来处理相关事件. 示例代码: @Override public void onCreateOptionsM

  • Python占用的内存优化教程

    概述 如果程序处理的数据比较多.比较复杂,那么在程序运行的时候,会占用大量的内存,当内存占用到达一定的数值,程序就有可能被操作系统终止,特别是在限制程序所使用的内存大小的场景,更容易发生问题.下面我就给出几个优化Python占用内存的几个方法. 说明:以下代码运行在Python3. 举个栗子 我们举个简单的场景,使用Python存储一个三维坐标数据,x,y,z. Dict 使用Python内置的数据结构Dict来实现上述例子的需求很简单. >>> ob = {'x':1, 'y':2,

  • iOS性能优化教程之页面加载速率详解

    前言 我认为在编码过程中时刻注意性能影响是有必要的,但凡事都有个度,不能为了性能耽误了开发进度.在时间紧急的情况下我们往往采用"quick and dirty"的方案来快速出成果,后面再迭代优化,即所谓的敏捷开发.与之相对应的是传统软件开发中的瀑布流开发流程. 卡顿产生的原因 在 iOS 系统中,图像内容展示到屏幕的过程需要 CPU 和 GPU 共同参与.CPU 负责计算显示内容,比如视图的创建.布局计算.图片解码.文本绘制等.随后 CPU 会将计算好的内容提交到 GPU 去,由 GP

  • mysql 8.0.18 安装配置优化教程

    Mysql安装.配置.优化,供大家参考,具体内容如下 Mysql下载 首先登入官网下载mysql的安装包,官网地址https://dev.mysql.com/下拉到最后选择downloads里的 MySQL Community Server 选择所需下载的版本 MySQL安装 1.打开下载的mysql安装文件mysql-5.5.43-win32.rar,双击解压缩,运行"setup.exe". 2.选择安装类型,有"Typical(默认)"."Comple

  • MySQL中对表连接查询的简单优化教程

    在MySQL中,A LEFT JOIN B join_condition执行过程如下: · 根据表A和A依赖的所有表设置表B. · 根据LEFT JOIN条件中使用的所有表(除了B)设置表A. · LEFT JOIN条件用于确定如何从表B搜索行.(换句话说,不使用WHERE子句中的任何条件). · 可以对所有标准联接进行优化,只是只有从它所依赖的所有表读取的表例外.如果出现循环依赖关系,MySQL提示出现一个错误. · 进行所有标准WHERE优化. · 如果A中有一行匹配WHERE子句,但B中没

  • MySQL针对Discuz论坛程序的基本优化教程

    过了这么久,discuz论坛的问题还是困扰着很多网友,其实从各论坛里看到的问题总结出来,很关键的一点都是因为没有将数据表引擎转成InnoDB导致的,discuz在并发稍微高一点的环境下就表现的非常糟糕,产生大量的锁等待,这时候如果把数据表引擎改成InnoDB的话,我相信会好很多.这次就写个扫盲贴吧. 1. 启用innodb引擎,并配置相关参数 #skip-innodb innodb_additional_mem_pool_size = 16M #一般16M也够了,可以适当调整下 innodb_b

随机推荐