首页
Preview

理解并解决数据库中的N+1问题(PHP实例)

N+1问题是一个指在数据库中发送大量的SQL查询,从而增加负载并导致性能下降的问题。当你使用框架进行开发时,你有没有意识到你可能无意中发送了大量的SQL查询?

更具体地说,N+1问题是指在一个过程中,首先通过一个查询获取父数据,然后获取子数据,每获取一个子数据都会生成一个额外的查询,这种状态不断重复。这就是所谓的N+1问题。

以下是一个在PHP代码中出现N+1问题的例子。在循环中调用了另一个表,并在每次循环中基于父数据的emp_no发出SQL查询:

<?php
$connection = mysqli_connect("主机名", "用户名", "密码", "数据库名");

$employeesQuery = "SELECT * FROM employees";
$employeesResults = mysqli_query($connection, $employeesQuery);

// N+1问题正在发生。基于父数据的emp_no在循环中发出SQL查询。
while ($employee = mysqli_fetch_assoc($employeesResults)) {
    $empNo = $employee['emp_no'];
    $salariesQuery = "SELECT * FROM salaries WHERE emp_no = '$empNo'";
    $salarieResults = mysqli_query($connection, $salariesQuery);
    // 处理
}

mysqli_close($connection);
?>

因为在循环中调用了另一个表,所以该PHP代码产生了N+1问题:

为了解决N+1问题,有两个策略:

1、预先加载(Eager Loading)

预先加载是一种预先获取相关数据的方法。以下的SQL查询在获取父记录时同时获取子记录,从而避免了N+1问题:

SELECT *
FROM employees
JOIN salaries
ON employees.emp_no = salaries.emp_no;

2、批处理加载(Batch Loading)

批处理加载是一种基于父数据的ID,一次性获取所有子数据的方法。这样可以避免N+1问题,并能够一次性获取所需的所有数据:

SELECT *
FROM salaries
WHERE emp_no IN (id1, id2, id3);

总的来说,处理数据库时,有预先加载和批处理加载等方法。要避免冗余的数据库访问。

版权声明:本文内容由TeHub注册用户自发贡献,版权归原作者所有,TeHub社区不拥有其著作权,亦不承担相应法律责任。 如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

点赞(0)
收藏(0)
大熊
暂无描述

评论(0)

添加评论