简体   繁体   English

控制Eloquent作用域的运行顺序

[英]Control the run order of Eloquent scopes

I have a simple Eloquent scope that I would like to always run after all the other "Where" statements in the final query to optimize the efficiency of the query.我有一个简单的 Eloquent scope,我希望始终在最终查询中的所有其他“Where”语句之后运行,以优化查询效率。 I would like it to run last, no matter where I put it in the query builder (it's for a large application where this scope has been used many times, and I'd like it to be fool-proof in the future)我希望它最后运行,无论我把它放在查询生成器的哪个位置(它用于一个大型应用程序,这个 scope 已经被多次使用,我希望它在未来是万无一失的)

I'll put the scope below, but it's exactly the same as the example in the Eloquent documentation.我将 scope 放在下面,但它与 Eloquent 文档中的示例完全相同。

    public function scopeActive($query)
    {
        $query->where('active', 1);
    }

I know eloquent is smart enough to put ordering statements after Where statements, so maybe there's a trick to use that logic to manipulate the order of the where statements, but so far I can't see it.我知道 eloquent 足够聪明,可以在 Where 语句之后放置排序语句,所以也许有一个技巧可以使用该逻辑来操纵 where 语句的顺序,但到目前为止我还看不到它。 I'm using MySQL if there's some kind of raw sql I can run.如果有某种原始的 sql 我可以运行,我正在使用 MySQL。

SELECT ...
    WHERE foo > 123
      AND active = 1

will [probably] run faster if you have如果你有,[可能]会跑得更快

INDEX(active, foo)

Note that, regardless of where active=1 is in the WHERE clause, putting active _first in the INDEX` is optimal.请注意,无论active=1WHERE子句中的何处,将active _first in the INDEX` 中是最佳的。

My point here is "always run after other Wheres" is not the proper goal to try to achieve.我在这里的观点是“总是追赶其他地方”并不是试图实现的正确目标。 So...所以...

I don't know if Eloquent can 'automatically' add such a statement, but maybe we can achieve the equivalent goal inside MySQL. (There are a hundred frameworks that try to hide MySQL from the user. I cannot learn them all; instead, I try to help users work around the framework deficiencies. The framework user needs to learn both the framework and the underlying database.)我不知道 Eloquent 是否可以“自动”添加这样的语句,但也许我们可以在 MySQL 中实现等效的目标。(有一百个框架试图向用户隐藏 MySQL。我无法全部学习;相反,我试图帮助用户解决框架的不足。框架用户需要同时学习框架底层数据库。)

  • Create a VIEW on top of the TABLE , where the VIEW : SELECT * FROM tbl WHERE active = 1 .TABLE之上创建一个VIEW ,其中VIEW : SELECT * FROM tbl WHERE active = 1 Then tell Eloquent to access that View instead of the underlying Table.然后告诉 Eloquent 访问该视图而不是底层表。 (I suspect the framework's syntax is the same.) (我怀疑框架的语法是一样的。)
  • Add active, to the beginning of most of the indexes for the table (Views cannot be indexes.)active,添加到的大多数索引的开头(视图不能是索引。)

If you need to discuss this further (either before or after making such changes), please provide SHOW CREATE TABLE and EXPLAIN SELECT... There could be other issues make my advice not as good as I hope.如果您需要进一步讨论(在进行此类更改之前或之后),请提供SHOW CREATE TABLEEXPLAIN SELECT...可能还有其他问题使我的建议不如我希望的那么好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM