我在Yii2中有很多关系:RecipeUnit - IngredientWeight - Ingredient。在RecipeUnit模型中:
public function getIngredientWeights()
{
return $this->hasMany(IngredientWeight::className(), ['recipe_unit_id' => 'id']);
}
public function getIngredients()
{
return $this->hasMany(Ingredient::className(), ['id' => 'ingredient_id'])
->via('ingredientWeights');
}
使用以下代码ActiveQuery生成两个SQL而不是一个连接,并且需要很长时间($model
是具有id
= 4的RecipeUnit实例):
$model->getIngredients()->orderBy('sort_order')->limit(1)->one()
SELECT * FROM `dh_ingredient_weight`
WHERE `recipe_unit_id`=4 (2977 records 57.1 ms)
SELECT * FROM `dh_ingredient`
WHERE `id` IN ('4', '5', ..., '5536')
ORDER BY `sort_order` LIMIT 1 (1 record 2.7 ms)
如果我使用hasMany
/ viaTable
代替hasMany
/ via
,结果是一样的:
public function getIngredients()
{
return $this->hasMany(Ingredient::className(), ['id' => 'ingredient_id'])
->viaTable(IngredientWeight::tableName(), ['recipe_unit_id' => 'id']);
}
但是没有hasMany会生成正常的连接,运行得非常快:
public function getIngredients()
{
return Ingredient::find()->joinWith(['ingredientWeights'])->where([
'{{%ingredient_weight}}.recipe_unit_id' => $this->id]);
}
SELECT `dh_ingredient`.* FROM `dh_ingredient`
LEFT JOIN`dh_ingredient_weight`
ON `dh_ingredient`.`id` = `dh_ingredient_weight`.`ingredient_id`
WHERE `dh_ingredient_weight`.recipe_unit_id=4
ORDER BY `sort_order` LIMIT 1 (1 record 0.2 ms)
问题是,如果关系是在没有hasMany
/ via
的最后一个例子中定义的,是否有任何不利之处?