我有这两个查询,第一个是使用 Active Record
编写的,第二个是使用 yii\db\Query
自定义制作的。在我的本地主机查询中,用 Query 编写的查询速度快 2-4 毫秒,但更难编写。此外,使用 AR 编写的查询将执行多个数据库查询以及 SHOW CREATE TABLE 查询,总计比我执行 AR 时执行的查询多 10 或 12 个。此外,AR 要求您为关系网络中的每个表定义 AR 模型,而如果您避免使用 AR,您最终会在您的应用程序中使用更少的类/文件。
我的问题是,您会使用 AR 还是会使用 yii\db\Query
编写查询? AR 更漂亮也更容易编写,但它会生成如此多的查询,这是个问题吗?我在一个网站上工作,该网站的表格有几百万行,每天大约有 10 万次网站访问。
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();
最佳答案
首先,可以缓存您的架构并避免那些“SHOW CREATE TABLE”查询。使用 db
对象的 enableSchemaCache
属性设置它。
其次,联接并不总是填充相关记录的最佳方式。例如,如果表 A 中的每个条目在表 B 中都有许多相关条目,则将 B 连接到 A 将导致表 A 中的条目重复。这可能是一个性能问题。
因此 yii2 有 with()
和 joinWith()
。使用 with()
获取相关表将进行 2 次查询,但通常这样做效率更高。
最后,AR 是一种非常方便的工具,一旦您掌握了它的窍门。对我来说,它的好处大于开销。
关于php - Yii2:使用 Query 与 ActiveRecord 构建复杂查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30944095/