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

标签 sql orm select-n-plus-1

我对数据库缺乏经验,刚刚阅读了 "n+1 selects issue" .我的后续问题:假设数据库与我的程序驻留在同一台机器上,缓存在 RAM 中并正确索引,为什么 n+1 查询模式很慢?

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

SELECT * FROM Cars;

/* for each car */
SELECT * FROM Wheel WHERE CarId = ?

用我对数据库缓存的心智模型,每个SELECT * FROM Wheel WHERE CarId = ?查询应该需要:
  • 1 次查找到达“Wheel”表(一个哈希图 get())
  • 1 次查找以到达具有指定 CarId 的 k 个轮子的列表(另一个哈希图 get())
  • k 次查找以获取每个匹配轮的轮行(k 指针取消引用)

  • 即使由于内部存储器结构的原因,我们将其乘以一个小的常数因子以获得额外的开销,它仍然应该非常快。进程间通信是瓶颈吗?

    编辑 :我刚刚通过 Hacker News 找到了这篇相关文章:Following a Select Statement Through Postgres Internals. - HN discussion thread .

    编辑 2 :为了澄清,我确实假设 N要大。一个不平凡的开销会增加一个明显的延迟,是的。我首先要问的是,对于上述设置,为什么开销并不小。

    最佳答案

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

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

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

    总而言之,如果数据库是本地的,避免 n+1 次选择的重要性要小得多,但如果 n 很大,则仍然很重要。

    关于sql - 为什么 n+1 选择模式很慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26245404/

    相关文章:

    mysql - 错误代码 : 1060 Duplicate column name 'NA'

    c# - 分组 2 个表,计算值,然后将结果保存在字典中

    c# - 使用 MySQL .Net Core ADO 执行多查询

    nhibernate - CQRS - 查询端

    android - 如何有效地执行嵌套 SQL 查询

    SQL - 如何选择单词末尾具有某些值的单词

    python - psycopg2 - 如何在更新 Json 列时转义单引号?

    database - 更新插入

    entity-framework - 使用 Entity Framework 和 where 查询而不创建大量查询(避免 N+1)

    python - 是否可以使用 Flask/SQLAlchemy/Pytest/SQLite 计算 SQL 查询的数量?