问题标签 [select-n-plus-1]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
729 浏览

java - Hibernate 在使用查询缓存时执行 N+1 个选择而不是 1 个查询

我被一个问题困住了,我真的很迷茫,不知道该怎么办。我使用查询缓存+二级缓存,我想将结果正确缓存10秒。所以这是我的

ehcache.xml

首先,我使用insert()方法填充我的数据库。然后,我第一次调用我的select()方法来获取数据。一切正常 - 查询和实体被缓存,如果我在 2 秒后调用select()方法,我将在没有对数据库的任何请求的情况下获取数据。然后我等待 12 秒(以使缓存完全过期),调用select()并在再次调用select()后 2 秒。这就是我得到 n+1 选择的地方:

2019-02-13 18:52:17,101 [DEBUG] org.hibernate.engine.jdbc.spi.SqlStatementLogger.logStatement(SqlStatementLogger.java:92) 选择 testentity0_.id 作为 id1_0_0_,testentity0_.value 作为 value2_0_0_ 来自 test testentity0_ where testentity0_ .id=? 2019-02-13 18:52:17,107 [DEBUG] org.hibernate.engine.jdbc.spi.SqlStatementLogger.logStatement(SqlStatementLogger.java:92) 选择 testentity0_.id 作为 id1_0_0_,testentity0_.value 作为 value2_0_0_ 从 test testentity0_ 哪里 testentity0_ .id=? 2019-02-13 18:52:17,108 [DEBUG] org.hibernate.engine.jdbc.spi.SqlStatementLogger.logStatement(SqlStatementLogger.java:92) 选择 testentity0_.id 作为 id1_0_0_, testentity0_.value 作为 value2_0_0_ 从 test testentity0_ where testentity0_ .id=? 2019-02-13 18:52:17,108 [调试] org.hibernate.engine.jdbc.spi.SqlStatementLogger.logStatement(SqlStatementLogger. java:92) 选择 testentity0_.id 作为 id1_0_0_, testentity0_.value 作为 value2_0_0_ 从 test testentity0_ where testentity0_.id=? 2019-02-13 18:52:17,109 [DEBUG] org.hibernate.engine.jdbc.spi.SqlStatementLogger.logStatement(SqlStatementLogger.java:92) 选择 testentity0_.id 作为 id1_0_0_,testentity0_.value 作为 value2_0_0_ 从 test testentity0_ where testentity0_ .id=?

我知道发出这些请求是因为查询缓存仅缓存 id,而且二级缓存中似乎缺少这些 id 的实体。但为什么他们失踪了?当我启用完整日志记录时,我看到在第三次调用select()之后有日志条目,例如

将实体添加到二级缓存:[TestEntity#1]

因此,如果实体被添加到二级缓存并且它们应该只在 11 秒后过期,为什么它们会在 2 秒后丢失?

我的pom.xml的一部分:

持久性.xml

测试实体.java

主.java

PS我猜这个问题的原因是Hibernate中的一个错误。如果我从 5.2 升级到 5.4,问题就会消失。但是我接受弗拉德的回答,因为它通常包含有用的信息。

0 投票
1 回答
708 浏览

python - 如何修复“在 `LogEntry.user` 上检测到潜在的不必要的急切负载”

我正在使用插件nplusonehttps://github.com/jmcarp/nplusone)创建一个新的 Django 2.2 项目。当我尝试继续 /admin URL 时,我收到下一个错误“检测到潜在的不必要的急切负载LogEntry.user”当我在 DB 中至少有 1 条记录时会出现此问题。

模型.py

管理员.py

调试 SQL

0 投票
1 回答
323 浏览

ruby-on-rails - Rails:这个 SQL 查询被多次调用,我被优化为急切加载

在此处输入图像描述

我在 rails simple activerecord 查询中看到了上述问题

这两个查询都不是任何其他查询的一部分,这意味着不包含在任何连接/包含查询中。但是对于一个独立的查询,为什么会出现这个问题?

仅仅因为一个操作被多次调用,不同的输入不能被称为 N+1 查询问题。

0 投票
3 回答
107 浏览

php - 如何将数据库中的信息添加到现有的对象数组中?

我有一个以下格式的数组;

我需要修改数据并向该数组添加另一个键/值。我需要使用userId数组中的值,查询 MySQL 数据库并返回值。我需要为每个数组元素执行此操作。

因此,对于每个数组元素,我想运行一个查询,例如;

然后我想将此值添加到数组中,最终数组应如下所示;

我知道我可以通过使用向数组元素添加一个附加值array_walk,就像这样;

我不确定如何从数据库中检索值并插入到现有数组中。

我怎样才能做到这一点?

0 投票
1 回答
224 浏览

java - 在使用 JPA 和 Hibernate 进行测试期间检测 N+1 查询问题

我们正在使用https://github.com/vladmihalcea/db-util这是一个很棒的工具,但是我们面临着关于会话缓存的挑战,正如另一个问题中提到的那样,它不能被禁用

因此,以下测试失败,因为findOne从会话缓存中获取对象:

entityManager.clear()每次调用都有一个解决方法SQLStatementCountValidator.reset()

现在,解决方法很好,但容易出错,因为现在我们必须注入 EntityManager 作为测试的依赖项,并记住entityManager.clear()在保存代表我们场景的所有对象后调用。

问题

  1. 实现这一目标的最佳方法是什么?
  2. 您是否希望 SQLStatementCountValidator 也清除 entityManager?

在这里可以查看日志语句(最后一条)


解决方法代码如下所示:

0 投票
1 回答
222 浏览

php - Doctrine 在水合过程中添加了额外的查询,导致“正常”一对一和自引用关系出现 n+1 问题

News使用一对多自引用方法相互关联(一个消息是父消息,可以有多个子消息)。更重要的是,每个都有正常的(非自引用的)与andNews的一对一关系。当我运行简单的 DQL 时:EventGallery

然后通过设置getResults默认HYDRATION_OBJECT值的方法对结果进行水合,在getResults方法内部的某处进行额外的查询。

第一次查询选择的新闻的子项在哪里news_id = 1和是什么。news_id = 2

News也没有自我引用的一对多关系(我在这里忽略了它们),但是水合作用不会对它们进行额外的查询。仅当语句中parent涉及关系时才会出现问题。where

如何重现

Gallery实体类似于,Event所以我在这里忽略了它。

有 20 个孩子的 Hydrationnews最终得到:20 * 2 + 1 (n*r+1) 个查询,其中:

  • (n) 20 是孩子的数量
  • (r) 2 是一对一关系的数量
  • 1是基本查询

我想防止对 Doctrine 进行的一对一关系的额外查询。是 Doctrine 错误还是不受欢迎的行为,还是我在某个地方犯了错误?

总而言之,我只想让所有自引用的孩子没有一对一的关系,因为我没有要求检索它们,所以它应该只使用一个查询来获取所有孩子news,而不需要对每个检索到的“新闻”进行额外的查询对象和每个对象都是一对一的关系。

0 投票
2 回答
517 浏览

ruby-on-rails - How to avoid N + 1 queries with self-referential table in Rails

How to I correctly use includes to avoid N + 1 queries in this situation:

I have a set of categories that can be nested (i.e., they form a tree). For example:

  • Teaching
    • Course 1
      • Office Hours
      • Lecture
    • Course 2
      • Office Hours
      • Lecture
  • Research
    • Project 1
    • Project 2
  • Service

To set up this hierarchy, each Category record has parent_id as a foreign key.

This is my Rails model:

I access all the categories for a given user using

However, every call to @categories[i].children generates a new query.

How do I correctly use includes so that I can access each category's child categories without additional queries.

(I also tried @categories = Category.where(user_id: user.id).includes(:children) with no change in behavior.)

0 投票
1 回答
25 浏览

ruby-on-rails - 包括与条件的左连接 has_many 关联

如果不触发 N+1 查询,我似乎无法执行关联查询。

假设我举办派对。我有很多朋友,每次有朋友来参加聚会,他们都会创建一个 Presence。

所以:

到目前为止,一切都很好。

我想获得我每个朋友的列表,知道他们是否在这个聚会上,而不触发 N+1 查询。

我的数据集如下所示:

等等。

当然,我有很多朋友,也参加过很多聚会。(这当然是一个虚构的例子。)

我会做:

我总是可以在 Ruby 层进行过滤:

但这as_json(includes: {})与等等一起工作得非常糟糕。我发现这很容易出错,因为我将对结果进行计算。

而且我举办了很多派对,你知道吗?(仍然是虚构的)

如果我在第一个查询中的位置,我会丢失左连接:

没想到今晚,布雷特和一帮一直都在的朋友缺席了。(这不保证是虚构的体验)

我只会看到在场的朋友。

如果我通过party,当然我也不会看到谁缺席。

现在我知道有一些方法可以在 SQL 中做到这一点,还有其他方法我们可以围绕一些 Ruby 来将它们组合在一起。

但是,我正在寻找一种在 Activerecord 中执行此操作的“一流”方法,而无需获得 N+1。

有没有办法只使用 Activerecord 工具来做到这一点?我还没有找到任何东西。

0 投票
1 回答
293 浏览

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

我有一个使用 SQLAlchemy 和数据库的 Flask 项目。为了测试,我将数据库替换为 SQLite 数据库。

现在我想运行一些视图并测试执行的查询数量。本质上,我想避免意外遇到 (n+1) 选择问题。是否可以从 SQLite 或 Pytest / Flask 插件获取执行的 SQL 查询的数量?

0 投票
1 回答
70 浏览

django - serpy.MethodField 的 Django N+1 问题

我使用nplusone来检测 N+1 个查询。

我有一个序列化实例的serpy序列化程序。OrderAnOrder有一个cartOrderComponent实例组成的,如下所示。代码简化:

Order通过以下方式获取序列化实例列表OrderListView

OrderSerializer定义如下。nplusone没有说明在哪里检测到 N+1 查询,所以我已经注释掉了所有可能的罪魁祸首并找到了真正的罪魁祸首。我已经在评论中指出它们在哪里。

我一生都无法弄清楚为什么我的预取在这里不起作用。Django Debug Toolbar 确认它不是误报:

如果我objget_cart_servicesor中检查get_cart_products,我看到那obj._prefetched_objects_cache["cart"]QuerySetof OrderComponent。例如,如果我obj在中进行检查,我在 中看不到任何东西,这是我没有预料到的,因为and是-ed,而不是-ed。SimpleOrderComponentSerializer.get_product_nameobj._prefetched_objects_cache["cart"]listing.productlisting.serviceselect_relatedprefetch_related

我承认我不完全理解它是如何工作的,但我假设select_related在一个查询中贪婪地填充一对一的关系,而不是懒惰地等待相关对象被请求。

从外观上看,我的初始值prefetch_related不会“延续”到内部序列化程序的MethodField处理程序中。nplusone日志:

是因为cart是“反向”关系吗?任何帮助理解为什么这不起作用将不胜感激。