是否可以让雄辩的查询构建器返回StdClass
而不是Model
?
例如,User::where('age', '>', 34)->get()
会返回Collection
个User
个模型。
DB::table('users')->where('age', '>', 34)->get()
会返回Collection
个StdClass
个对象。快多了。
因此:
是否可以防止水合雄辩模型并将StdClass
对象作为数据库查询构建器返回,但仍然可以利用雄辩查询构建器的有用性语法?
我不明白为什么这个问题被投票否决了。它的期望和措辞非常明确。人们应该将鼠标悬停在低投票图标上并看到建议“这个问题没有显示出任何研究成果;它不清楚且无益。”
Laravel社区坚信,如果你走出Eloquent,你就会过早地进行优化。这是不正确的,在有10,000多行保湿的情况下,数据库结果中的Eloquent模型极其缓慢。我们正在谈论秒,有时几十秒和沉重的记忆。
Laravelers然后会说“只做一个DB::query()
更快”。是的......是的...它是我意识到的......虽然我在这个问题中提出问题......就在这里......上面......措辞简洁明了......我可以使用 Eloquent Query Builder 构建查询并返回StdClass对象,以便不会为数千个Eloquent模型带来所有开销。我已经听说Laravelers“为什么不用DB::query()
呢?”因为我不要求...我问我们是否可以使用 Eloquent语法,它比连接更容易,更易读....
我不在这里询问有关应用程序架构的建议。我们希望这样做有很多深层原因,例如匹配我们的ElasticSearch存储库的输出等......但我不应该深入了解原因 - 这是一个问答论坛。不是讨论或建议平台。
答案 0 :(得分:4)
首先,这是一个非常好的问题。所有那些人都在那里讨厌,让OP休息一下!他是亲Laravel,这不是一个Eloquent sucks
问题,真是太酷了。
在我看来,
保湿模型很少影响应用程序性能
那里有很多ORM,如果你看一下任何框架,这些问题就会不断涌现 - 但事实上,正如我已经意识到的那样,ORM几乎不会影响性能。
匪徒往往是查询本身而不是 ORM
让我举几个例子说明为什么Eloquent模型可能比DB facade查询慢?
<强> 1。模特活动:
如果您的模型中有model events(例如保存,创建等),它们有时会降低处理速度。不是说应该避免事件,你只需要小心何时何时不使用它们
<强> 2。加载关系:
无数次我看到人们使用Eloquent提供的appends列表加载关系,有时模型有5-10个关系。每次启动Eloquent查询时,这都是5-10个连接!如果将它与数据库外观查询进行比较,肯定会更快。但话说回来,谁是真正的罪魁祸首?不是ORM,它是查询(带有额外的连接!)
作为一个例子,不久有人问a question on this,他/她想知道为什么Eloquent查询比原始查询慢。看看吧!
第3。不了解触发Eloquent查询的内容
这是迄今为止人们认为ORM较慢的最重要原因。他们通常(并非总是)不明白触发查询的内容。
例如,假设您要更新products
表并将产品#25的价格设置为250美元。
也许,您在控制器中写下以下内容:
$id = 25;
$product = Product::findOrFail($id);
$product->price = 250;
$product->save();
然后,你的同事说嘿,这太慢了。尝试使用DB facade。所以你写道:
$id = 25;
DB::table('products')->where('product_id', $id)->update(['price' => 250]);
繁荣!它更快。同样,罪魁祸首不是ORM。这是查询。上面的一个实际上是2个查询,findOrFail
触发select *
查询,save
触发更新查询。
您可以而且应该使用Eloquent ORM将其写为单个查询,如下所示:
Product::where('product_id', 25)->update(['price' => 250]);
查询优化的一些优秀做法
让您的数据库完成大部分工作而不是PHP :例如。而不是迭代Eloquent集合,可能以数据库为您工作的方式构建数据库查询。
单个更新的批量更新:非常明显。避免在for循环中保存模型,yuk!
对于繁重的查询,请使用事务:数据库事务避免对每个插入重新编制索引。如果您确实需要在单个函数调用中调用数千个插入/更新查询,请将它们包装到事务中
最后但并非最不重要,如果有疑问,请检查您的查询:如果您曾经有过怀疑,或许ORM是真正的罪魁祸首 - 请再想一想!检查您的查询,尝试并优化它。
如果ORM正在减慢速度,请使用obervers或Laravel debugbar来比较有和没有ORM的查询。通常情况下,你会发现查询是不同的,区别不在于水合作用,而是实际的查询本身!
答案 1 :(得分:1)
是的,可以使用'getQuery'或'toBase'方法。例如:
User::where('age', '>', 34)->getQuery()->get();
或
User::where('age', '>', 34)->toBase()->get();