为什么n + 1选择模式慢?

Per*_*ids 5 sql orm select-n-plus-1

我对数据库缺乏经验,只读过"n + 1选择问题".我的后续问题:假设数据库与我的程序驻留在同一台机器上,缓存在RAM中并正确编制索引,为什么n + 1查询模式会变慢?

举个例子,让我们从接受的答案中获取代码:

SELECT * FROM Cars;

/* for each car */
SELECT * FROM Wheel WHERE CarId = ?
Run Code Online (Sandbox Code Playgroud)

使用我的数据库缓存的心理模型,每个SELECT * FROM Wheel WHERE CarId = ?查询都需要:

  • 1次查找到达"Wheel"表(一个hashmap get())
  • 1查找到达指定CarId(另一个hashmap get())的k轮列表
  • k查找以获取每个匹配轮的轮行(k指针解除引用)

即使我们将它乘以一个小的常数因子,因为内部存储器结构会产生额外的开销,但它仍然应该是不明显的快速.进程间通信是瓶颈吗?


编辑:我刚刚通过黑客新闻发现了这篇相关文章:通过Postgres内部发表选择声明.- HN讨论主题.

编辑2:为了澄清,我认为N是大的.一个非平凡的开销会加起来明显延迟,是的.我问的是,对于上述设置,为什么开销在一开始就是非平凡的.

mer*_*ike 5

你是正确的,避免n + 1选择在你描述的场景中不太重要.如果数据库位于远程计算机上,则通信延迟> 1ms是常见的,即cpu将花费数百万个时钟周期等待网络.

如果我们在同一台机器上,通信延迟要小几个数量级,但与另一个进程的同步通信必然涉及一个上下文切换,通常成本> 0.01 ms(),这是数万个时钟周期.

此外,ORM工具和数据库每个查询都会有一些开销.

总而言之,如果数据库是本地的,那么避免n + 1选择就不那么重要了,但是如果n很大则仍然很重要.