问题标签 [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.
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,问题就会消失。但是我接受弗拉德的回答,因为它通常包含有用的信息。
python - 如何修复“在 `LogEntry.user` 上检测到潜在的不必要的急切负载”
我正在使用插件nplusone
(https://github.com/jmcarp/nplusone)创建一个新的 Django 2.2 项目。当我尝试继续 /admin URL 时,我收到下一个错误“检测到潜在的不必要的急切负载LogEntry.user
”当我在 DB 中至少有 1 条记录时会出现此问题。
模型.py
管理员.py
调试 SQL
php - 如何将数据库中的信息添加到现有的对象数组中?
我有一个以下格式的数组;
我需要修改数据并向该数组添加另一个键/值。我需要使用userId
数组中的值,查询 MySQL 数据库并返回值。我需要为每个数组元素执行此操作。
因此,对于每个数组元素,我想运行一个查询,例如;
然后我想将此值添加到数组中,最终数组应如下所示;
我知道我可以通过使用向数组元素添加一个附加值array_walk
,就像这样;
我不确定如何从数据库中检索值并插入到现有数组中。
我怎样才能做到这一点?
java - 在使用 JPA 和 Hibernate 进行测试期间检测 N+1 查询问题
我们正在使用https://github.com/vladmihalcea/db-util这是一个很棒的工具,但是我们面临着关于会话缓存的挑战,正如另一个问题中提到的那样,它不能被禁用。
因此,以下测试失败,因为findOne
从会话缓存中获取对象:
entityManager.clear()
每次调用都有一个解决方法SQLStatementCountValidator.reset()
。
现在,解决方法很好,但容易出错,因为现在我们必须注入 EntityManager 作为测试的依赖项,并记住entityManager.clear()
在保存代表我们场景的所有对象后调用。
问题
- 实现这一目标的最佳方法是什么?
- 您是否希望 SQLStatementCountValidator 也清除 entityManager?
在这里可以查看日志语句(最后一条)
解决方法代码如下所示:
php - Doctrine 在水合过程中添加了额外的查询,导致“正常”一对一和自引用关系出现 n+1 问题
News
使用一对多自引用方法相互关联(一个消息是父消息,可以有多个子消息)。更重要的是,每个都有正常的(非自引用的)与andNews
的一对一关系。当我运行简单的 DQL 时:Event
Gallery
然后通过设置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
,而不需要对每个检索到的“新闻”进行额外的查询对象和每个对象都是一对一的关系。
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
- Course 1
- 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.)
ruby-on-rails - 包括与条件的左连接 has_many 关联
如果不触发 N+1 查询,我似乎无法执行关联查询。
假设我举办派对。我有很多朋友,每次有朋友来参加聚会,他们都会创建一个 Presence。
所以:
到目前为止,一切都很好。
我想获得我每个朋友的列表,知道他们是否在这个聚会上,而不触发 N+1 查询。
我的数据集如下所示:
等等。
当然,我有很多朋友,也参加过很多聚会。(这当然是一个虚构的例子。)
我会做:
我总是可以在 Ruby 层进行过滤:
但这as_json(includes: {})
与等等一起工作得非常糟糕。我发现这很容易出错,因为我将对结果进行计算。
而且我举办了很多派对,你知道吗?(仍然是虚构的)
如果我在第一个查询中的位置,我会丢失左连接:
没想到今晚,布雷特和一帮一直都在的朋友缺席了。(这不保证是虚构的体验)
我只会看到在场的朋友。
如果我通过party
,当然我也不会看到谁缺席。
现在我知道有一些方法可以在 SQL 中做到这一点,还有其他方法我们可以围绕一些 Ruby 来将它们组合在一起。
但是,我正在寻找一种在 Activerecord 中执行此操作的“一流”方法,而无需获得 N+1。
有没有办法只使用 Activerecord 工具来做到这一点?我还没有找到任何东西。
python - 是否可以使用 Flask / SQLAlchemy / Pytest / SQLite 计算 SQL 查询的数量?
我有一个使用 SQLAlchemy 和数据库的 Flask 项目。为了测试,我将数据库替换为 SQLite 数据库。
现在我想运行一些视图并测试执行的查询数量。本质上,我想避免意外遇到 (n+1) 选择问题。是否可以从 SQLite 或 Pytest / Flask 插件获取执行的 SQL 查询的数量?
django - serpy.MethodField 的 Django N+1 问题
我使用nplusone来检测 N+1 个查询。
我有一个序列化实例的serpy序列化程序。Order
AnOrder
有一个cart
由OrderComponent
实例组成的,如下所示。代码简化:
Order
通过以下方式获取序列化实例列表OrderListView
:
OrderSerializer
定义如下。nplusone
没有说明在哪里检测到 N+1 查询,所以我已经注释掉了所有可能的罪魁祸首并找到了真正的罪魁祸首。我已经在评论中指出它们在哪里。
我一生都无法弄清楚为什么我的预取在这里不起作用。Django Debug Toolbar 确认它不是误报:
如果我obj
在get_cart_services
or中检查get_cart_products
,我看到那obj._prefetched_objects_cache["cart"]
是QuerySet
of OrderComponent
。例如,如果我obj
在中进行检查,我在 中看不到任何东西,这是我没有预料到的,因为and是-ed,而不是-ed。SimpleOrderComponentSerializer.get_product_name
obj._prefetched_objects_cache["cart"]
listing.product
listing.service
select_related
prefetch_related
我承认我不完全理解它是如何工作的,但我假设select_related
在一个查询中贪婪地填充一对一的关系,而不是懒惰地等待相关对象被请求。
从外观上看,我的初始值prefetch_related
不会“延续”到内部序列化程序的MethodField
处理程序中。nplusone
日志:
是因为cart
是“反向”关系吗?任何帮助理解为什么这不起作用将不胜感激。