ChatGPT解决这个技术问题 Extra ChatGPT

Laravel Eloquent 与 DB 外观:为什么使用 Eloquent 并降低性能? [关闭]

关闭。这个问题需要更加集中。它目前不接受答案。想改进这个问题?更新问题,使其仅通过编辑此帖子专注于一个问题。 2年前关闭。改进这个问题

我在 Laravel's DB facade query builderLaravel's Eloquent ORM 之间做了一些性能测试。对于许多 SQL 语句(SELECT、UPDATE、DELETE、INSERT),DB 外观比 Eloquent 快得多。

那么为什么有人会使用更慢的 Laravel Eloquent 而不是更快的 DB 外观呢?

不要比较苹果和橘子。 Eloquent 是一个 ORM,这意味着可以自动为您处理模型的关系。您无需编写复杂的查询即可检索相关模型。您甚至可以在完全没有任何数据库知识的情况下检索数据库信息。此外,Eloquent 还具有查询构建器所缺乏的大量额外功能,例如可读性、访问器、修改器、JSON/数组转换、隐藏敏感属性、自动时间戳、自动属性转换、软删除等......
苹果生产苹果汁,橙子生产橙汁。但不幸的是,EloquentQuery Builder 都从 database 产生了相同的东西,data。可能这就是他比较这两者的原因。
@JaviStolz 如果您会说“不知道 SQL”,那您是对的。但是“你甚至可以在没有任何数据库知识的情况下检索数据库信息”是不可能的。 Eloquent 要求您了解数据库的结构、外键是什么以及它们是如何工作的,以及如何浏览该结构。只有最简单的查询不需要数据库知识,大多数应用程序都需要高度复杂的查询。
虽然苹果制造苹果汁,橙子制造橙汁,但它们都是果汁。 Eloquent 返回 Collections,这是包装在帮助器中的数据,这使得业务逻辑更具可读性。 Query Builder 是 Eloquent 使用的一块。 Eloquent 是业务逻辑范式中的一个组件,它允许您使用 Closure 在流程的每个部分进行调整和过滤数据,因此您的内容在决策树下运行时会读取 $object->filter($something_we_just_calculated)。你可以把 Eloquent 想成 JQuery
你的苹果和橙子的例子是无效的,现在已经指出了很多。但是您是如何设法将您的评论编辑了 3 次却仍然有这么多错误的呢? @JaviStolz

J
JustAMartin

Eloquent 是 Laravel 对 Active Record 模式的实现,它具有所有优点和缺点。

Active Record 是以 CRUD 方式处理单个实体的一个很好的解决方案——也就是说,创建一个具有填充属性的新实体,然后将其保存到数据库、从数据库加载记录或删除。

您将从 Eloquent 的功能中受益匪浅,例如脏检查(仅针对已更改的字段发送 SQL UPDATE)、模型事件(例如,当有人创建新帐户时发送管理警报或更新统计计数器)、特征(时间戳、软删除、自定义特征)急切/延迟加载等。您还可以应用域驱动模式并在 Active Record 实体中实现一些业务逻辑,例如验证、管理关系、计算等。

但是,正如您已经知道的那样,Active Record 带有一些性能价格。

当您处理单个记录或几条记录时,无需担心。但是对于读取大量记录的情况(例如,对于数据网格、报告、批处理等),普通的 Laravel DB 方法是一种更好的方法。

对于我们基于 Laravel 的应用程序,我们正在使用我们认为合适的两种方法。我们使用 Laravel 的 Eloquent for UI 表单来处理单个记录,并使用 DB 方法(由 SQL 视图支持,并带有额外的数据库引擎特定的性能调整)来检索 UI 表的数据、导出任务等。它也适用于 RESTful API - Eloquent 用于 GET、PUT、POST、DELETE 与键和 DB 用于 GET 没有键但具有过滤器和排序和分页。


急切加载不能解决性能问题吗?
@Christophvh 有时急切的加载会有所帮助,但它仍然是相同的 Eloquent (Active Record) 对象及其所有“重物”。 Laravel 在 Eloquent 模型上提供了一些方便的方法来使 SQL 查询和检索的对象变得更轻,但这不再是纯粹的 Eloquent,而是某种 Eloquent / QueryBuilder 的混合体。
Eloquent 非常适合在单个模型上进行常规 CRUD 操作或在处理少量记录时进行简单的 JOIN,但是一旦您开始进行复杂的连接并在事务中处理数百或数千条记录,查询构建器方法的性能会更高;如果有的话,原始 SQL 是性能最高的选项,因为它是直接查询。
仍然同意答案,因为现在我面临着同样的方式,即使用 eloquent 中的不同检查/规则加载(SELECT)是一种痛苦,但如果我们不从一开始就计划好,将所有这些都转移到查询构建器中也是一个很大的挑战我们需要使用 DB 查询,如何处理 eloquent,希望其他人知道这一点
@Adam 在一些类似 ERP 的商业网站中,客户需要每页 100 条记录的大型网格,通常所有这些记录本质上都是只读视图,通常基于有效的微调 SQL 视图。所以,这里真的不需要繁重的 Eloquent 模型,除非你想花一些时间为实体的只读版本创建单独的 Eloquent 模型。对于大型数据网格,创建一个解析所有连接等的 SQL 视图并返回记录作为 Laravel 的数据库机制可以处理的简单平面图的效率要高得多。
A
Aryan Beezadhur

是的,在某些情况下你是对的。

当您处理更多数据时,最好使用 Laravel 的 DB 外观查询构建器,而不是 Laravel 的 Eloquent ORM。

从性能测试来看,在一个简单的表中插入 1000 行需要 Eloquent 1.2 秒,而 DB 门面只需要 800 毫秒。

那么为什么要使用 Eloquent 呢?口才也很重要,因为:

它的语法比 DB 外观更简单。

对于不懂 SQL 的开发人员来说更容易。您需要了解 SQL 才能使用 DB 门面。

使用 Eloquent 编写的代码比使用 DB 外观编写的代码更具可读性和可维护性: // With Eloquent $student = App\Student::find($id); // 使用 DB 门面 $student = DB::table('student')->where('id', $id)->first();

如果你想更改数据库,使用 Laravel Eloquent 会更容易,因为它可以处理许多不同的数据库,而 DB 门面需要你编写 SQL,这可能需要为不同的数据库重写。

因此,当您在一个小型站点上使用简单的 CRUD 操作时使用 Eloquent,当您使用 Eloquent 不支持的许多连接和其他功能时使用 DB 外观。

现实生活中的例子:

你正在制作一个大学网站,其中包含 5,000 名教师和 10,000 名学生,以及一些通知和文件。使用 Laravel Eloquent 构建这个站点会更好,因为它简单易读。你正在制作一个像 Stack Overflow 这样的高流量网站,它每月为超过 1 亿人提供服务,并拥有超过 7000 万个帖子。最好使用 DB 外观,因为它更快,并且会显着加快响应时间。

您可以使用 Laravel Debugbar 检查查询性能。

Here 是 Eloquent 和 DB 门面之间的性能、内存消耗和代码质量的完整比较。


A
Aryan Beezadhur

为什么使用 Laravel Eloquent 而不是 DB 门面:

您可以编写面向对象的代码。它比编写原始 SQL 或使用 DB 外观更容易使用。没有绑定到表模式,所以例如如果你想改变你的表名,你不必触及单个 Eloquent 查询,只需更改 Eloquent 模型中的表名。可以以优雅的方式维护表之间的关系。只需提及关系类型(JOIN、LEFT JOIN、RIGHT JOIN 等)即可从相关表中获取数据。 Eloquent 查询比原始 SQL 或 DB 外观更具可读性。您可以在模型内部使用方法、范围、访问器、修饰符等,这是一种可维护的模式。


M
Mohammad Naji

当谈到性能和应用程序增长时,为了比较,请查看下表:

Eloquent ORM 平均响应时间:

平均连接数(毫秒) 1 162.2 3 1002.7 4 1540.0

原始 SQL 平均响应时间:

平均连接数(毫秒) 1 116.4 3 130.6 4 155.2

Article Reference


这些比较是针对极端情况的,这些查询构建了 1000 个(如果不是 10,000 个)雄辩的 ORM 模型,其中只会在现实世界中用于批量数据处理,这是有道理的,为什么它更慢。但是对于绝大多数情况,这是针对 < 100 个条目的基本 crud(假设您正确限制了查询),即使对大型商业应用程序也有微小的影响,因为减速的主要原因是模型的创建。我认为得出的结论只有在处理大量数据时才重要。
A
Arthur Tarasov

这只是我的看法,不是一个全面的答案。在给定的情况下,我使用任何更方便的方法。

如果我遇到用 eloquent 或查询生成器编写的包或代码,我会使用正在使用的任何内容。

如果我从头开始创建一些东西,我发现查询构建器会更直观,因此我会更频繁地使用它。

对于 Laravel,似乎开发应用程序的易用性和速度比性能更重要。我真的很喜欢它们使一切变得非常容易,即使对于那些对 php/mysql 知之甚少的人也是如此。在某些情况下,eloquent 比查询生成器更容易。在其他情况下,反之亦然。我认为有很多方法可以让 Laravel 变得如此简单和对新手友好。


P
Patrick N.

Eloquent ORM 最适合在特定表中处理较少的数据。另一方面,查询构建器在处理一个或多个表中的大量数据时花费的时间比 Eloquent ORM 更快。

就我而言,我在一个包含少于 17500 个条目的表的应用程序中使用 ELoquent ORM。每当我预计该表将包含超过 17500 个条目时,查询生成器是最好的。

此外,在具有子查询的应用程序中,我更喜欢查询构建器而不是 ELoquent ORM。


我很好奇为什么是17500?
N
Nitesh Mangla

他们之间有很多不同

生成器查询比您通过调试器测试的 ORM 快得多。这是测试 https://scotch.io/tutorials/debugging-queries-in-laravel 的方法。当您处理大量数据时,构建器查询的执行时间更少,例如数据库中的数据比 ORM 多 1,00,000。 Builder 查询最适合大量数据。Orm 最适合使用关系,因为它提供了许多关系方法来定义表之间的关系。生成器查询使用 sql 的连接,但 orm 使用关系来处理 2 个表或更多表。


H
HENG Vongkol

在从数据库构建复杂查询时,我喜欢使用查询生成器,因为它看起来很容易使用。对于单表工作,我喜欢雄辩。