标签: eager-loading

Rails急切加载似乎是在查询错误

我正试图在我的Rails 3应用程序中加载.我把它缩小到一个非常基本的样本,而不是生成我期望的一个查询,它产生4.

首先,这是我的模型的简单细分.

class Profile < ActiveRecord::Base
  belongs_to :gender

  def to_param
    self.name
  end
end

class Gender < ActiveRecord::Base
  has_many :profiles, :dependent => :nullify
end
Run Code Online (Sandbox Code Playgroud)

然后我有一个ProfilesController :: show动作,我在那里查询模型.

def ProfilesController < ApplicationController
  before_filter :find_profile, :only => [:show]

  def show
  end

  private

    def find_profile
      @profile = Profile.find_by_username(params[:id], :include => :gender)
      raise ActiveRecord::RecordNotFound, "Page not found" unless @profile
    end
end
Run Code Online (Sandbox Code Playgroud)

当我查看生成的查询时,它显示以下内容:

SELECT `profiles`.* FROM `profiles` WHERE `profiles`.`username` = 'matt' LIMIT 1
SELECT `genders`.* FROM `genders` WHERE (`genders`.`id` = 1)
Run Code Online (Sandbox Code Playgroud)

我期望看到的是一个查询:

SELECT `profiles`.*, `genders`.* …
Run Code Online (Sandbox Code Playgroud)

ruby-on-rails query-optimization eager-loading ruby-on-rails-3

3
推荐指数
1
解决办法
1047
查看次数

按照建议添加急切负载后,Rails 子弹宝石速度变慢

我添加了项目符号 gem来建议我开发中的任何 N+1 查询(Rails 4.0.2),它建议急切地加载模型的两个父关联,在其中显示其所有记录。

在急切加载这些所属关联之一之前:

Completed 200 OK in 5252ms (Views: 1.8ms | ActiveRecord: 114.1ms)
Run Code Online (Sandbox Code Playgroud)

急切加载后:

Completed 200 OK in 6741ms (Views: 2.1ms | ActiveRecord: 146.0ms)
Run Code Online (Sandbox Code Playgroud)

此外,通过急切加载,浏览器会在控制台显示已完成后挂起,并且在一段时间内(大约 6 秒)不会更新。服务器生产没有这种冻结问题,但在这种情况下,急切加载仍然是一个糟糕的建议。

急切加载会变慢是否有意义?该视图确实访问(预先加载的)父记录。

此外,由于某种原因,子弹宝石不显示调用堆栈。

ruby-on-rails eager-loading rails-bullet

3
推荐指数
1
解决办法
780
查看次数

EF Eager加载包括多个

我有这个存储库:

public class Repository<T> : IRepository<T> where T : class
{
    private readonly DbContext context;
    private readonly DbSet<T> dbEntitySet;

    public Repository(DbContext context)
    {
        if (context == null)
            throw new ArgumentNullException("context");

        this.context = context;
        this.dbEntitySet = context.Set<T>();
    }

    public IEnumerable<T> GetAll()
    {
        return this.dbEntitySet;
    }

    public IEnumerable<T> GetAll(string include)
    {
        return this.dbEntitySet.Include(include);
    }

    public IEnumerable<T> GetAll(string[] includes)
    {
        IQueryable<T> query = context.Set<T>();
        foreach (var include in includes)
            query.Include(include);

        return query;
    }

    public void Create(T model)
    {
        this.dbEntitySet.Add(model);
    }

    public void Update(T …
Run Code Online (Sandbox Code Playgroud)

c# entity-framework eager-loading

3
推荐指数
1
解决办法
1319
查看次数

Laravel动态关系 - 在渴望加载时访问模型属性

我在Laravel模型上有一个雄辩的关系,它是动态的 - 也就是说,特定数据库字段的值决定了哪个模型将被加载.当我第一次实例化模型实例然后引用关系时,我能够很好地加载这种关系,但是当我急切地加载这种关系时它不起作用.

具体来说,我有一个Product模型.该产品可能是也可能不是其他产品的父母.如果parent_id产品的设置被设置为0那么该产品被视为父产品(无论是否有孩子).如果将parent_id其设置为其他产品的ID,则该产品是子产品.我需要能够访问Product::with('parent')和知道的parent关系将返回要么本身(是的,重复的数据),或者不同的产品,如果它是一个孩子.

这是我到目前为止的关系:

public function parent()
{
    if ($this->parent_id > 0) {
        return $this->belongsTo('App\Product', 'parent_id', 'id');
    } else {
        return $this->belongsTo('App\Product', 'id', 'id');
    }
}
Run Code Online (Sandbox Code Playgroud)

当我急切加载时,$this->parent_id总是未定义,因此即使它实际上是父产品,这种关系也只会自行返回.

关系被急切加载之前,有没有办法访问模型的属性?在我返回关系之前,我考虑过在单独的查询中工作,但我意识到我甚至无法访问产品的id来运行该查询.

如果不可能,还有哪些其他方法可以解决这类问题?这似乎不能通过传统的多态关系来解决.我只有两个可能的想法:

  • belongsTo在我动态确定外键的关系中添加某种约束.
  • 创建我自己的自定义关系,该关系使用基于不同数据库字段的外键.

老实说,我不知道如何实现其中任何一个.我是以正确的方式来做这件事的吗?有什么我可以忽略的吗?


在考虑了这个之后,我认为提出问题的最简单方法是:有没有办法在运行时为关系本身内部的关系动态选择外键?当我调用关系时,我的用例不允许我使用急切的加载约束 - 约束需要应用于关系本身.

php eager-loading laravel eloquent laravel-5

3
推荐指数
1
解决办法
3974
查看次数

Symfony/doctrine:优化 n+1 查询

语境

想象一组提案,其中每个用户都可以对提案投赞成票或反对票。

所以我有2个模型:

  • Proposal
  • A Vote,与 a proposal、 auser和 an opinion(向上或向下)相关。

现在我想显示我的所有提案,包括每个提案的额外信息:

  • 多少赞?
  • 投了多少票?
  • 当前用户是否已投票?
  • 当前用户是否已投反对票?

 问题

这真的很容易实现,但这意味着每个提案显示 4 个请求(称为 n+1 查询问题)。我来自 Rails 世界,在那里可以使用预先加载或一些棘手的查询轻松解决此问题。但是我无法用教义解决它,需要一些帮助!

我试过的

 使用魔法领域

第一种解决方案是进行自定义查询:选择所有提案,包括赞成票、反对票的数量,当前用户是否赞成或反对。

查询现在返回4分列比模型来描述:count_upvotescount_downvoteshas_user_upvotedhas_user_downvoted

为了与学说一起使用,我必须将这些字段添加到我的Proposal实体中。

对我来说,这不是一个好的解决方案,因为它意味着始终使用此查询来避免混蛋模型,其中这些字段可以为空。

使用摘要

第二种解决方案是让视图使用另一个对象。这个对象是用一个参数创建的:当前用户。该对象由优化查询创建,包含以下方法:

  • getAllProposals()
  • getUpvotes($a_proposal)
  • getDownvotes($a_proposal)
  • hasUserUpvoted($a_proposal)
  • hasUserDownvoted($a_proposal)

对我来说,仅仅为了视图优化而被迫创建一个对象真的太过分了。

使用扩展实体

这第三个解决方案使用唯一的查询来获取提案、他们的赞成票、反对票,并检查用户是否赞成或反对。

它创建了一个新的“扩展”实体,

public function __construct(
    Proposal $badgeProposal,
    $upvotesCount,
    $downvotesCount,
    $hasUserUpvoted,
    $hasUserDownvoted
) {
Run Code Online (Sandbox Code Playgroud)

对我来说,这是更好的解决方案,但目前这行不通,因为我不知道如何简单地从 SQL 行中获取建议(但我几乎没有搜索)。

轮到你了

那么,还有什么其他解决方案呢?对于学说开发人员来说,是必须是一个众所周知的问题。

sql doctrine eager-loading symfony

3
推荐指数
1
解决办法
2213
查看次数

Laravel 5.4 - 如何对急切加载关系进行分页

我有以下代码来检索给定部分的线程及其评论及其喜欢。它有效,但我想对结果进行分页。

return $this->threads()->where('state', '=', 'active')->with('comments.likes')->get();
Run Code Online (Sandbox Code Playgroud)

一种方法是这样做,但它会导致大量查询,因为它不急于加载。

return $this->threads()->where('state', '=', active)->paginate(5);
Run Code Online (Sandbox Code Playgroud)

有什么方法可以急切加载所有数据并利用 Laravel 的分页魔法?

pagination relationship eager-loading laravel

3
推荐指数
1
解决办法
4099
查看次数

调用保存时触发Railsbelongs_to

假设我有 User 1-n 和 UserNotification

问题是我不知道为什么每次我尝试保存 UserNotification 时,rails auto SELECT the user of that UserNotification 都会触发 n + 1 问题

例如

UserNotification.where(id: [1,2,3]).update(updated_at: Time.current)
Run Code Online (Sandbox Code Playgroud)

将生成这些 SQL

 UserNotification Load (0.4ms)  SELECT `user_notifications`.* FROM `user_notifications` WHERE `user_notifications`.`id` IN (1, 2, 3)
  User Load (0.3ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` IN (3, 1)
  User Load (0.2ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 4
Run Code Online (Sandbox Code Playgroud)

UserNotification 模型很简单belongs_to :user

我已经阅读了更新源代码,但仍然不知道

有任何想法吗 ?

ruby-on-rails associations eager-loading

3
推荐指数
1
解决办法
405
查看次数

活动模型序列化器不急于加载关系

我正在使用Bullet gem来查看应用程序中的n + 1个查询。它告诉我taggings在调用序列化程序时急于加载我的关联。我的代码如下所示:

render json: @products, each_serializer: ::V1::ProductSerializer, includes: [:taggings], links: links, status: :ok
Run Code Online (Sandbox Code Playgroud)

但是添加完之后,我仍然从Bullet gem得到同样的警告。看起来像这样:

GET /api/v1/product_feed?state=CA&page=1
USE eager loading detected
  Product => [:taggings]
  Add to your finder: :includes => [:taggings]
Call stack
  /home/jay/current_projects/api/app/controllers/api/v1/products_controller.rb:111:in `product_feed'
Run Code Online (Sandbox Code Playgroud)

有谁知道为什么不急于加载标签表。

ruby ruby-on-rails eager-loading active-model-serializers

3
推荐指数
1
解决办法
633
查看次数

FindAll 包含涉及复杂的多对(多对多)关系(sequelizejs)

在 Software Engineering SE 中一个兄弟问题

考虑Company,ProductPerson

Company和之间存在多对多的关系Product,通过一个联结表Company_Product,因为给定的公司可能生产不止一种产品(如“汽车”和“自行车”),但也可能生产一种给定的产品,如“汽车” , 可由多家公司生产。在连接表中Company_Product有一个额外的字段“价格”,它是给定公司销售给定产品的价格。

还有另一种之间的许多一对多的关系Company_Product,并Person通过结合表Company_Product_Person。是的,它是一种多对多关系,涉及一个已经是联结表的实体。这是因为一个人可以拥有多种产品,例如公司 1 的汽车和公司 2 的自行车,而同一个 company_product 可以由多个人拥有,因为例如,person1 和 person2 都可以从公司1. 在连接表中Company_Product_Person有一个额外的字段“想法”,其中包含购买 company_product 的人的想法。

我想和查询sequelize从数据库中获得的所有实例Company,与所有相关的Products与各Company_Product后者又包括所有相关Persons与各自的Company_Product_Persons

获取两个连接表的元素也很重要,因为字段“价格”和“想法”很重要。

我无法弄清楚如何做到这一点。

为了调查这个问题,我尽可能缩短了代码。看起来很大,但大部分都是模型声明样板:(要运行它,先做npm install sequelize sqlite3

const Sequelize = require("sequelize");
const sequelize = new Sequelize({ dialect: …
Run Code Online (Sandbox Code Playgroud)

javascript many-to-many eager-loading node.js sequelize.js

3
推荐指数
1
解决办法
2732
查看次数

使用相关模型的Count加载laravel eloquent模型

鉴于我有两个雄辩的模型:预订和客户。

当我将所有预订与相应客户一起列出时,我还想显示相应客户的总预订量(此预订的数量 + 所有其他预订)。

示例输出:

  • 预订 1:客户 A(总共有 20 个预订)
  • 预订2:客户B(总共有10个预订)
  • 预订3:客户C(VIP:总共有100个预订)

为了避免 n+1 问题(显示此内容时每个预订额外查询一个),我想bookingsCount为客户急切加载。

关系是:

预订: public function customer() { return $this->belongsTo(Customer::class) }

顾客: public function bookings() { return $this->hasMany(Booking::class) }

使用预先加载查询预订的示例

工作,但没有急切地加载bookingsCount:

Booking::whereNotCancelled()->with('customer')->get();
Run Code Online (Sandbox Code Playgroud)

不工作:

Booking::whereNotCancelled()->with('customer')->withCount('customer.bookings')->get();
Run Code Online (Sandbox Code Playgroud)

我了解到,您不能withCount在相关模型的字段上使用,但您可以创建一个hasManyThrough关系并调用withCount该关系,例如Booking::whereNotCancelled()->withCount('customerBookings');请参阅此处接受的答案)。

但是:这不起作用。我想,这是因为一个预订属于一个客户,而一个客户有许多预订。

这是类 Booking 的 hasManyThrough 关系

public function customerBookings()
{
    // return the bookings of this booking's customer
    return $this->hasManyThrough(Booking::class, Customer::class);
}
Run Code Online (Sandbox Code Playgroud)

这是 hasManyThrough 的失败测试

/**
 * @test …
Run Code Online (Sandbox Code Playgroud)

php eager-loading laravel eloquent

3
推荐指数
1
解决办法
2252
查看次数