首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Yii2:使用Query构建复杂查询

Yii2:使用Query构建复杂查询
EN

Stack Overflow用户
提问于 2015-06-19 17:34:36
回答 2查看 2.9K关注 0票数 4

我有这两个查询,第一个是使用Active Record编写的,第二个是使用yii\db\Query定制的。在我用查询编写的localhost查询中,使用查询编写的查询速度要快2-4毫秒,但更难编写。此外,用AR编写的查询将更多地执行多个数据库查询,再加上显示CREATE查询,总的来说,当我执行AR时,会执行更多的10或12个查询。此外,AR要求您为关系网络中的每个表定义AR模型,而如果您避免AR,则应用程序中的类/文件将减少。

我的问题是,您是使用AR还是使用yii\db\Query编写查询?AR更漂亮,更容易编写,但是它会产生这么多的查询,这是一个问题吗?我正在一个网站上工作,那里的桌子有几百万行,每天有大约100,000次的网站访问。

AR查询:

代码语言:javascript
复制
return self::find()->select('id, news_users_id')
                   ->with([
                        'newsUsers' => function ($query) {
                            $query->select(['ID', 'cmpid']);
                        },
                    ])
                   ->with([
                        'newsUsers.firme' => function ($query) {
                            $query->select(['id', 'skraceni_naziv']);
                        },
                    ])
                   ->with([
                        'newsUsers.firmeBh' => function ($query) {
                            $query->select(['id', 'skraceni_naziv']);
                        },
                    ])
                   ->with([
                        'newsUsers.firmeOstalo' => function ($query) {
                            $query->select(['id', 'skraceni_naziv']);
                        },
                    ])
                   ->orderBy(['id' => SORT_DESC])
                   ->limit(6)
                   ->all();

查询:

代码语言:javascript
复制
$query = new Query;

$query->select(['club.id',
                'firme.id', 'firme.skraceni_naziv',
                'firme_bh.id', 'firme_bh.skraceni_naziv',
                'firme_ostalo.id', 'firme_ostalo.skraceni_naziv']) 

      ->from('club')
      ->innerJoin('news_users', 'club.news_users_id = news_users.ID')
      ->leftJoin('firme', 'news_users.cmpid = firme.id')
      ->leftJoin('firme_bh', 'news_users.cmpid = firme_bh.id')
      ->leftJoin('firme_ostalo', 'news_users.cmpid = firme_ostalo.id')
      ->orderBy(['club.id' => SORT_DESC])
      ->limit(6);

$command = $query->createCommand();

return $command->queryAll();
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-06-20 21:34:02

首先,可以缓存模式并避免那些“显示创建表”查询。使用enableSchemaCache对象的db属性设置它。

其次,联接并不总是填充相关记录的最佳方式。例如,如果表A中的每个条目在表B中都有许多相关条目,则将B连接到A将导致表A中的条目重复出现。这可能是一个性能问题。

因此,yii2有with()joinWith()。使用with()获取相关表将产生2个查询,但通常情况下,这样做更有效。

最后,AR是一个非常方便的工具,一旦你掌握了它的诀窍。对我来说,它的好处超过了间接费用。

票数 4
EN

Stack Overflow用户

发布于 2015-06-20 21:24:01

首先: ActiveRecord::find()方法返回扩展查询类的ActiveQuery实例。因此,您可以使用ActiveRecord::find()对查询对象执行所有操作。

区别在于: ActiveQuery几乎没有额外的方法,包括'with‘方法,这与'join’方法不一样,因为它运行的是您已经处理过的额外db请求。由于使用了ActiveQuery和“with”方法,您将ActiveRecord对象作为主要结果及其关系。另一方面,查询将只返回作为数组的数据库数据,因此您将错过您的ActiveRecord方法。

如果性能很重要,您最好通常使用联接,因为它只需要一个db请求。但是,大量的联合数据对于性能也是至关重要的。所以我相信如果你在表现上有麻烦的话,你会需要一些特别的决定。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30944095

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档