【问题标题】:Should I use Eloquent ORM or create big joins by Fluent?我应该使用 Eloquent ORM 还是通过 Fluent 创建大连接?
【发布时间】:2014-08-23 09:09:12
【问题描述】:

好吧,我正在将 Eloquent ORM 用于我正在开发的项目,但它让我遇到了性能问题。当我只使用它自己的方法时,我可以通过它的查询日志看到它创建了很多查询。

我正在尝试从具有 4 个其他表的主表中获取数据,其中一个与它一对一相关,另一个与它多对多相关。 Eloquent 为它创建了大约 6-7 个查询,这让我担心性能问题。然后,我删除 Eloquent 的方法并使用 Fluent 创建巨型查询,使用大量连接,这使我失去了代码的可读性和实用性。

我真正需要知道的是:Eloquent 会牺牲性能吗?我应该坚持下去,还是只使用 Fluent?还有什么更好,几个大的连接查询还是更多的小查询?

【问题讨论】:

  • 事实上,这完全取决于您和您的应用程序。使用Eloquent 创建它。它可能会更容易和更快。然后当你需要提高性能时,重构需要重构的东西。还有其他方法可以改进它 - 从缓存开始。

标签: sql database laravel laravel-4 eloquent


【解决方案1】:

我将扩展 Sebastian 的答案。

我也有多对多的关系,甚至是一对多的关系。

我实际上已经将 Eloquent 的编程风格(看起来更容易)与 Fluent 的一些联合 hack 融合在一起。请注意,Eloquent 是 Fl​​uent 的扩展,因此除非您正在执行 bat 查询,否则您不会牺牲。

如果您使用一对一或一对多的 User 和 Phone 模型(一个用户可以有多个电话号码)

你只需 where()->get() 然后 $users->phone - 这将使 eloquent 为每个 ID 运行一个 select *。这是使用 Eager Loading(Sebastian 引用但太短而无法实际解释)的地方,它预取所需的所有 ID 并急切加载 ID(您可以通过运行查询日志分析器来验证这一点)。

这样做的额外好处是您可以像这样预先加载许多关系。

因此,如果您没有正确使用它,那么“Eloquent 是否会带来性能影响”的解决方案并不是干巴巴的。

下面是我如何使用 eloquent 和 fluent 的一个小例子: 在 Book Model 中 - 我定义了一个 Scope 函数,它是一个关系函数:

   public function scopeLicensorStatus($query, $licensor_status)
    {
        $query->select('book.*')
            ->leftJoin('licensors as l', 'l.id', '=', 'book.licensor_id')
            ->where('l.status','=',$licensor_status);
    }

    $bookData = Book::
        ->LicensorStatus('active')
        ->where('book.status','=', 'active')
        ->whereIN('book.id',$recommendedIds)
        ->take($limit)
        ->skip($offset)
        ->get();

这样做的作用是为我做一个函数加入,让我从外部链接命令。最后(如果您使用 toSQL() 而不是 get()),您将获得与原始 SQL 匹配的单个查询,但是如您所见 a)如果您打算将连接与其他约束重用,则代码是可重用的, b) 你不会牺牲速度,因为最终游戏查询是一个单一的(只需要正确编写即可),c) 看起来更好且可读,这就是我们喜欢 eloquent 的原因。

希望这个答案能帮助你更深入地了解雄辩

【讨论】:

  • 感谢您的解释。因此,如果我使用 Eager Loading 而不是 Fluent,这使我执行 2-3 个额外的查询(这将通过 Fluent 使用一些连接并最终得到大量冗余信息来实现),它可能不会显着影响性能服务器,会吗?
  • 正如我所解释的 - 急切加载不会消除连接。它所做的是,它不会获取两个表之间的 ID(或关系)并单独重新运行它们,而是预先加载这些 ID,然后将其加载到第二个查询中(因此解决了 N+1 迭代)。对于一对多来说,它工作得非常好。对于多对多,您可能需要进行一些操作。正如我在示例中给出的那样,我如何同时保持连接和使用 eloquent。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-08
  • 1970-01-01
  • 2011-06-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多