批量思想:解决 N+1 问题

批量思想:解决 N+1 问题

N+1 查询问题指的是当查询一个对象的列表数据的时候,会首先查询列表中的对象的 ID,然后循环生成单独的 SQL/RPC 去查询对象的详细数据。这会导致 SQL/RPC 查询过多问题。

业务场景:

在一个循环内多次执行 RPC 调用或者数据库操作。数据量小的时候问题不大,能跑起来。

随着业务的发展,数据量越来越大,或者要查询的 id 越来越多(特别是未加限制的时候),耗时部题可想而知,长尾会越来越多。

案例 1:

读取多条记录时在 for 循环中去分别读取单行。

1
2
3
4
for _, id := range ids {
record := GetDetail(id)
// do something ...
}

解决方案:

改批量(一次从存储中取出所有 id 的结果)

1
2
records := GetDetails(ids)
// do something ...

谚云:积羽沉舟,群轻折轴

上述场景是一个典型的 N+1 问题,不限于读取,写入亦然。它可能导致性能问题和增加数据库负载。

为了解决 N+1 问题,开发人员可以使用一些技术,如批量加载(batch loading)、批量更新(Bulk Updates),从而减少请求次数。通过优化数据库查询和加载策略,开发人员可以避免 N+1 问题,并提高应用程序的效率。

0%