Laravel Eloquent vs查询构建器-为什么使用eloquent降低性能


76

我在Laravel查询生成器和雄辩者之间进行了一些性能测试。使用各种sql语句(select-update-delete-insert),查询生成器要快得多。

所以我的问题是:为什么有人对普通查询生成器使用Laravel Eloquent?


22
不要比较苹果和桔子。Eloquent是ORM,这意味着它可以自动为您处理模型的关系。您可以检索相关模型而无需编写复杂的查询。您甚至可以根本不需要任何数据库知识就可以检索数据库信息。Eloquent还具有查询生成器所缺少的大量额外功能,例如可读性,访问器,变异器,JSON /数组转换,隐藏敏感属性,自动时间戳,自动属性转换,Sofdeletes等...
Javi Stolz

78
苹果生产苹果汁,橙子生产橙汁。但遗憾的是Eloquent,并Query Builder都产生了同样的事情,datadatabase。也许这就是他比较这两个原因的原因。
伊姆兰

4
@JaviStolz如果您会说“不知道SQL”,那将是正确的。但是“甚至根本不需要任何数据库知识就可以检索数据库信息”是不可能的。雄辩的要求您了解数据库的结构,什么是外键以及它们如何工作以及如何浏览该结构。仅最简单的查询不需要数据库知识,并且大多数应用程序将需要高度复杂的查询。
米歇尔·范·德·布朗克

尽管苹果制造苹果汁,橙子制造橙汁,但它们都是果汁。雄辩的回报集合是包装在助手中的数据,使业务逻辑更具可读性。Query Builder是Eloquent所利用的一部分。Eloquent是业务逻辑范式中的一个组件,它使您可以使用Closure进行调整并在流的每个部分过滤数据,因此您的$object->filter($something_we_just_calculated)工作将在决策树中进行读取。您可以想到像JQuery这样的Eloquent
Nathaniel Waddell,

Answers:


138

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

Active Record是一种以CRUD方式处理单个实体的好方法-即创建具有填充属性的新实体,然后将其保存到数据库,从数据库加载记录或删除。

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

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

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

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


1
渴望加载不能解决性能问题吗?
Christophvh

5
@Christophvh有时,Eager加载可能会有所帮助,但它仍然与所有“繁重的工作”相同的Eloquent(活动记录)对象。Laravel在Eloquent模型上提供了一些便利的方法,以使SQL查询和检索到的对象更加轻巧,但这不再是纯粹的Eloquent,而是某种Eloquent / QueryBuilder混合体。
JustAMartin

Eloquent非常适合在处理几个记录时在单个模型或简单JOIN上执行常规CRUD操作,但是一旦开始进入复杂的联接并在事务中处理成百上千个记录,查询构建器方法就会更加高效。如果有的话,原始SQL是最高性能的选择,因为它是直接查询。
OzzyTheGiant

仍然同意答案,因为现在我面临着一种相同的方式,即用雄辩的方式从不同的检查/规则加载(SELECT)会很痛苦,但是如果我们不从一开始就计划,那么将所有这些转移到查询构建器上也将面临很多挑战我们需要使用数据库查询什么,如何进行雄辩,希望其他人意识到这一点
Osify

只是要澄清一下:laravel雄辩的问题是模型的实例化。例如,laravelnew User()对返回的每个用户行进行操作。这可能只需要1毫秒,但是如果oyu有10,000条记录?通常甚至没有必要,因为有时您只想返回用户名。在那种情况下DB::select会更快。还要注意:雄辩并不是实现实现的标准。laravel改编了Symphony的实现,或者如果我没记错的话,在某个时候已经实现了。
Toskan

51

是的,在某些情况下您是对的。当我们拥有更多数据并且几乎在每个站点中时,数据确实不小。然后,最好使用DB Query而不是Eloquent Query

雄辩的VS DB性能问题中,我听说过,

要为一个简单的表插入1000行,Eloquent花费了1.2秒,在这种情况下,DB Facade仅花费了800毫秒(ms)。

那么,为什么那么雄辩呢?那没有必要吗?

答案是-雄辩也是必要的。原因-

当需要连接时,要创建更好的关系并使用非常简单的语法查看结果。

口才也是那些对SQL查询知识不多的人

MVC框架遵循代码可读性,代码可维护性的规则,您知道这是Eloquent。下面的代码比较。显然,口才更好。

// In Eloquent
$student = App\Student::find($id);

// In DB facade
$student = DB::table('student')->where('id', $id)->first();

最重要的部分是如果我们要更改其他数据库,那么原始查询将使我们非常头疼,在这种情况下,Laravel Eloquent会用一只手解决所有问题。它可以处理不同类型的数据库。

因此,当我们使用Eloquent和When DB门面时:

  1. 当我们使用简单的CRUD在一个简单的小型记录站点上工作并且没有记录时,请在此处使用Eloquent。
  2. 当我们处理大量记录时,使用DB Query比使用Eloquent更好。

因此,最后明确了-什么时候使用数据库查询,什么时候使用口才查询。

编辑-现实生活中的例子

  1. 我正在建立大学网站。其中可能包含最大值5,000 teachers and 10,000 students and some notices and files。然后最好使用非常标准且易读的简单Laravel Eloquent做到这一点。
  2. 现在,我正在制作一个类似Stackoverflow的网站。其中可能包含多个1,000,0000 (1 crore) posts and many more things。我将必须在那里选择常规的DB外墙。从如此多的记录中搜索帖子的速度更快。

您可以使用Laravel Debugbar检查查询性能(一个流行的软件包,用于检查口才/数据库查询性能/执行时间)

现在由您选择。你想做什么...

您可以在此处通过代码比较来查看完整的代码,并比较它们的性能,内存消耗和代码质量-https: //devsenv.com/tutorials/laravel-eloquent-vs-db-query-builder-performance-and-other-statistics


4
“当我们将处理大量记录时”应该是“当我们使用Eloquent不支持的许多联接和功能时”。当Eloquent不能急于加载时,会导致性能下降。目前,用Eloquent很难进行复杂的聚合和多列联接。如果您有一百万条记录,而您所要做的就是从一个表中选择一些记录,那么Eloquent的SQL和性能与DBQuery甚至直接PDO相同。
米歇尔·范德布朗克

简单而完美的答案
Juned Ansari

34

为什么Laravel雄辩:

  1. 以某种OOP方式执行查询。
  2. 比原始查询或易于使用query builder
  3. 与不绑定table schema。即,即使您更改表名,也无需触摸单个表query(可能有1000个query)来使其工作。只要雄辩地更改表名即可model
  4. 表之间的关系可以以优雅的方式维护。只需提及关系的类型,JOIN, LEFT JOIN, RIGHT JOIN查询中就不再需要其他任何东西(等等)来获取相关表的数据。
  5. 使用Eloquent与Query Builder进行比较时,查询具有很高的可读性。
  6. 您可以在易于维护的模型中使用方法,范围,访问器,修饰符等。

19

在性能和应用程序增长方面,为了进行比较,请在下表中进行掠夺:

口才ORM和原始SQL之间的选择操作平均响应时间的比较

雄辩的ORM平均响应时间

Joins | Average (ms) 
------+-------------
1     | 162,2 
3     | 1002,7 
4     | 1540,0 

Result of select operation average response time for Eloquent ORM 

原始SQL平均响应时间

Joins | Average (ms) 
------+-------------
1     | 116,4 
3     | 130,6 
4     | 155,2 

Result of select operation average response time for Raw SQL 

文章参考


5

这只是我的意见,而不是全面的答案。在给定情况下,我会使用更方便的方式。

如果遇到用雄辩或查询生成器编写的程序包或代码,我将使用所使用的任何东西。

如果我从头开始创建某些内容,我发现查询生成器会更直观,因此我会更频繁地使用它。

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


2

雄辩的ORM最适合处理特定表中的较少数据。另一方面,无论是在一个还是多个表中,查询生成器都比Eloquent ORM花费更少的时间来处理大量数据。

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

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


2

他们之间有很多不同

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

1

从数据库构建复杂查询时,我喜欢使用查询生成器,因为它似乎易于使用。对于使用单个表,我喜欢雄辩。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.