我有这两个查询,第一个是使用Active Record编写的,第二个是使用yii\db\Query定制的。在我用查询编写的localhost查询中,使用查询编写的查询速度要快2-4毫秒,但更难编写。此外,用AR编写的查询将更多地执行多个数据库查询,再加上显示CREATE查询,总的来说,当我执行AR时,会执行更多的10或12个查询。此外,AR要求您为关系网络中的每个表定义AR模型,而如果您避免AR,则应用程序中的类/文件将减少。
我的问题是,您是使用AR还是使用yii\db\Query编写查询?AR更漂亮,更容易编写,但是它会产生这么多的查询,这是一个问题吗?我正在一个网站上工作,那里的桌子有几百万行,每天有大约100,000次的网站访问。
AR查询:
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();查询:
$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();发布于 2015-06-20 21:34:02
首先,可以缓存模式并避免那些“显示创建表”查询。使用enableSchemaCache对象的db属性设置它。
其次,联接并不总是填充相关记录的最佳方式。例如,如果表A中的每个条目在表B中都有许多相关条目,则将B连接到A将导致表A中的条目重复出现。这可能是一个性能问题。
因此,yii2有with()和joinWith()。使用with()获取相关表将产生2个查询,但通常情况下,这样做更有效。
最后,AR是一个非常方便的工具,一旦你掌握了它的诀窍。对我来说,它的好处超过了间接费用。
发布于 2015-06-20 21:24:01
首先: ActiveRecord::find()方法返回扩展查询类的ActiveQuery实例。因此,您可以使用ActiveRecord::find()对查询对象执行所有操作。
区别在于: ActiveQuery几乎没有额外的方法,包括'with‘方法,这与'join’方法不一样,因为它运行的是您已经处理过的额外db请求。由于使用了ActiveQuery和“with”方法,您将ActiveRecord对象作为主要结果及其关系。另一方面,查询将只返回作为数组的数据库数据,因此您将错过您的ActiveRecord方法。
如果性能很重要,您最好通常使用联接,因为它只需要一个db请求。但是,大量的联合数据对于性能也是至关重要的。所以我相信如果你在表现上有麻烦的话,你会需要一些特别的决定。
https://stackoverflow.com/questions/30944095
复制相似问题