laravel 雄辩的 ORM 性能
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17546779/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Eloquent ORM Performance
提问by Craig Morgan
I have just been testing the performance Eloquent ORM in Laravel and was shocked to find a simple query taking over 3 seconds to perform compared to the normal Laravel query which finished in 0.1 seconds. I'm only returning 1500 records.
我刚刚在 Laravel 中测试了 Eloquent ORM 的性能,并惊讶地发现一个简单的查询需要超过 3 秒才能执行,而普通 Laravel 查询只需要 0.1 秒即可完成。我只返回 1500 条记录。
DB::table('t_organisations')->get(); - 0.12253594398499 seconds
Organisation::all(); - 3.6389181613922 seconds
Surely this can't be normal!? I don't think I have missed anything in the setup. My db is normalized. What could be the problem?
这肯定不正常吧!?我认为我没有遗漏任何设置。我的数据库已标准化。可能是什么问题呢?
回答by hilnius
When you do
DB::table('t_organisations')->get();
It fetches all results as an array (or objects) but does not hydrate them to the model. See this stackoverflow answerif you want a quick explanation.
当您这样做时,
DB::table('t_organisations')->get();
它会将所有结果作为数组(或对象)获取,但不会将它们混合到模型中。如果您想快速解释,请参阅此 stackoverflow 答案。
When you do
Organisation::all();
The hydration process takes place, which is why the request takes longer (you have to allocate all objects in the memory and fill them with the fields). There are many links/tuts on hydration optimization to help you better request your database, and avoid the hydration of objects when you don't need it.
当你做
Organisation::all();
Hydration 过程发生时,这就是为什么请求需要更长的时间(你必须分配内存中的所有对象并用字段填充它们)。有很多关于 hydration 优化的链接/tuts 可以帮助您更好地请求数据库,并避免在不需要时对象的 hydration。
回答by Craig Morgan
Thanks for all your replies.
感谢你的回复。
Here's the result of the mysql query log:
这是mysql查询日志的结果:
Organisation::all(); - 1.6772060394287 secs
组织::全部(); - 1.6772060394287 秒
130710 9:52:43 5 Connect seltec@localhost on seltec
5 Prepare set names 'utf8' collate 'utf8_unicode_ci'
5 Execute set names 'utf8' collate 'utf8_unicode_ci'
5 Close stmt
5 Prepare select * from `users` where `id` = ? limit 1
5 Execute select * from `users` where `id` = '2' limit 1
5 Close stmt
5 Prepare select * from `t_organisations`
5 Execute select * from `t_organisations`
130710 9:52:44 5 Close stmt
130710 9:52:45 5 Quit
DB::table('t_organisations')->get(); - 0.13963603973389 secs
DB::table('t_organisations')->get(); - 0.13963603973389 秒
130710 9:55:16 6 Connect seltec@localhost on seltec
6 Prepare set names 'utf8' collate 'utf8_unicode_ci'
6 Execute set names 'utf8' collate 'utf8_unicode_ci'
6 Close stmt
6 Prepare select * from `users` where `id` = ? limit 1
6 Execute select * from `users` where `id` = '2' limit 1
6 Close stmt
6 Prepare select * from `t_organisations`
6 Execute select * from `t_organisations`
6 Close stmt
6 Quit
So no difference there then.... which means the delay must lie in the Eloquent php code. Yes, I have xdebug installed and no I am not prepared to waste my time trying to figure out why it's slow!!! If it's faster in query builder, that's good enough for me!!
所以没有区别....这意味着延迟必须在于 Eloquent php 代码。是的,我已经安装了 xdebug,不,我不准备浪费我的时间试图找出为什么它很慢!!!如果它在查询构建器中更快,那对我来说就足够了!!
@Laravels' developers: great job on the framework. It's intuitive, deals with authorizations well, especially with the confide and entrust plugins from Leroy Merlin. You might want to have a look at the Eloquent performance issue though!!
@Laravels 的开发人员:该框架做得很好。它很直观,可以很好地处理授权,尤其是来自 Leroy Merlin 的 confide 和 entrust 插件。不过,您可能想看看 Eloquent 性能问题!
Cheers! Craig
干杯! 克雷格
回答by wizardjoe
Make sure to do a RESET QUERY CACHE to clear your MySQL query cache in between tests. From the timestamps you posted it looks like you did the Eloquent queries first, which means that they were probably cached by the time you did the second test. That would explain the huge performance differential, although I do suspect Eloquent to be a little bit slower than normal Laravel queries because of the additional overhead.
确保在两次测试之间执行 RESET QUERY CACHE 以清除 MySQL 查询缓存。从您发布的时间戳来看,您似乎首先进行了 Eloquent 查询,这意味着它们可能在您进行第二次测试时已被缓存。这可以解释巨大的性能差异,尽管我确实怀疑 Eloquent 由于额外的开销而比普通 Laravel 查询慢一点。