Laravel Eloquent - 效率低下

时间:2015-06-02 20:53:31

标签: php mysql laravel eloquent

我正在考虑用Laravel开发一个新网站。关于使用Eloquent连接表和检索数据,我正在阅读关于http://vegibit.com/laravel-eloquent-orm-tutorial/的教程。在最后一个示例中,他们基本上尝试进行连接,但Eloquent仍在执行两个查询而不是一个查询。雄辩是效率低下还是仅仅是一个糟糕的例子?看起来这可以简单地用一个左连接查询来完成。任何人都可以对此提供一些见解吗?有没有更好的方法来执行此查询?具体的例子是:

Route::get('/', function()
{
    $paintings = Painting::with('painter')->get();

    foreach($paintings as $painting){
        echo $painting->painter->username;
        echo ' painted the ';
        echo $painting->title;
        echo '<br>';
    }

});

以下查询中的结果:

string ‘select * from paintings‘ (length=25)
string ‘select * from painters where painters.id in (?, ?, ?)’ (length=59)
Leonardo Da Vinci painted the Mona Lisa
Leonardo Da Vinci painted the Last Supper
Vincent Van Gogh painted the The Starry Night
Vincent Van Gogh painted the The Potato Eaters
Rembrandt painted the The Night Watch
Rembrandt painted the The Storm on the Sea of Galilee

3 个答案:

答案 0 :(得分:3)

Eloquent对于快速构建内容非常有用,并且具有查询缓存功能,它非常易于使用,但对于需要随时间扩展的大型项目而言,它可能并不理想,我的方法是使用Repository模式合同,我仍然可以使用Eloquent的力量,并有一个系统,可以让我在需要时轻松改变实施。

答案 1 :(得分:0)

如果您想要获取单个查询中的所有数据以使用连接,那么您必须将其指定为:

Painting::join('Painter as p', 'p.IdPainter', '=', 'Painting.IdPainting')->get()

如果你需要一些有条件的话:

Painting::join('Painter as p', 'p.IdPainter', '=', 'Painting.IdPainting')->where('cond1', '=', 'value')->get();

个人雄辩是效率低下的,我更喜欢Doctrine。

答案 2 :(得分:0)

你的问题的简单答案:不。这不是低效率。

以Jorge描述的方式使用Eloquent确实破坏了它作为ORM的目的。

虽然您可以像给出的示例一样编写联接,但ORM实际上并没有考虑到这一点。

您给出的示例不是n+1 query(其中,循环中的每个项目都会运行其他查询 - 最糟糕的查询类型)。

使用输出报告的两个查询并不是一个巨大的开销,我认为你可以在生产中使用它。您使用Eloquent的'with'eager loading正是您应该在此背景下使用的。

n + 1查询(您要避免)的示例如下:

foreach (Book::all() as $book)
{
    echo $book->author->name;
}

如果Book::all()返回20本书,那么循环将总共执行21个查询。 1获取所有书籍,每次$book次迭代获得1本书以获取作者姓名。

将Eloquent与预先加载一起使用,结合缓存就足以最大限度地减少任何性能问题。

相关问题