导致n+1查询问题的常见错误通常围绕着数据库获取数据的方式,尤其是在使用对象相关映射(ORM)框架或手动编写数据库查询时。以下是这些错误的详细说明:
** 1。在单独查询中获取相关数据
n+1查询问题的主要原因是构造代码以首先用一个查询检索记录列表,然后为每个记录执行一个额外的查询以获取相关数据。例如,查询一个用户列表,然后单独查询每个用户的帖子,以查询用户的1查询,以及n是n是用户数量的帖子的n查询。这导致许多小查询,而不是一个优化的查询[1] [2] [3] [7]。
** 2。默认依靠懒惰加载
大多数ORM使用懒惰加载作为默认的获取策略,这意味着仅在明确访问时才获取相关实体。虽然如果不需要相关数据,则可以节省资源,但在迭代集合时会触发多个查询,从而在不知不觉中导致n+1问题。例如,访问每个博客文章的作者单独触发每个帖子的单独查询[5]。
** 3。盲目重复查询而没有上下文调整
在应用程序的不同部分中重复使用相同的查询,而无需剪裁它可能会导致不必要的数据检索并加剧N+1问题。未针对特定用例进行优化的查询可能会获取不完整的数据,从而促使其他查询以稍后获取相关信息[8]。
** 4。不使用急切的加载或查询优化技术
无法使用急切的加载(在初始查询中获取相关数据)或优化加入会导致多次往返数据库。当开发人员没有明确指示其ORM或查询构建器将相关实体加载在一起时,这会发生这种情况,从而导致许多小查询,而不是一个有效的一个[5] [6] [7]。
** 5。忽略多个往返对数据库的影响
开发人员有时认为许多小查询比一个复杂查询更快,但是每个查询都涉及网络延迟和处理开销。 N+1查询的累积效应显着减慢了应用程序响应时间并增加了数据库负载,尤其是随着数据量的增长[1] [3] [5]。
** 6。缺乏意识或发现问题
因为n+1模式中的每个单独查询都很快运行,所以它通常不会出现在慢速查询日志或监视工具中,从而使其成为无声的性能杀手。在应用程序的响应能力显着降低之前,开发人员可能不会注意到问题[2] [5] [7]。
总而言之,n+1查询问题主要是由于特定于数据提取模式的效率低下,对每个记录的单独查询查询相关数据,而不是批处理或加入查询。这通常是由ORM中默认的懒惰加载,不使用急切的加载或批处理以及无需优化的通用查询而引起的。结果是降低性能和可伸缩性的过多数据库往返[1] [2] [3] [5] [6] [7]。
引用:
[1] https://planetscale.com/blog/what-is-n-1-query-problem-and-problem-and-and-how-to-solve-it
[2] https://stackoverflow.com/questions/97197/what-is-the-n1-selects-problems-problem-in-orm-object-rational-Real-Mappation
[3] https://www.pingcap.com/article/how-to-solficely-solve-the-n1-query-problem//
[4] https://evnedev.com/blog/development/the-n1-query-problem-what-is-it-is-is-and-how-do-you-solve-it/
[5] https://digma.ai/n1-query-problem-and-how-to-detect-it/
[6] https://www.linkedin.com/posts/aftab-ahmed-bb002827_avoiding-the-the-n1-query-problem-a-common-acmon-activity-7270527662970818561-zmz6
[7] https://dev.to/lovestaco/the-n1-query-problem-the-silent-performance-killer-2b1c
[8] https://www.okoone.com/spark/technology-innovation/avoid-these-7-sql-mistakes-for-better-database-management/