Activerecord Yi2 hasMany/via vs.hasMany/viaTable vs.find/joinWith
我在Yii2中有一个多对多关系:接受单位重量成分。在RecipeUnit型号中:Activerecord Yi2 hasMany/via vs.hasMany/viaTable vs.find/joinWith,activerecord,yii2,relation,Activerecord,Yii2,Relation,我在Yii2中有一个多对多关系:接受单位重量成分。在RecipeUnit型号中: public function getIngredientWeights() { return $this->hasMany(IngredientWeight::className(), ['recipe_unit_id' => 'id']); } public function getIngredients() { return $this->hasMany(Ingredien
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为id
=4的RecipeUnit实例):
如果我使用hasMany
/viaTable
而不是hasMany
/via
,结果是一样的:
public function getIngredients()
{
return $this->hasMany(Ingredient::className(), ['id' => 'ingredient_id'])
->viaTable(IngredientWeight::tableName(), ['recipe_unit_id' => 'id']);
}
但如果没有HASSANY,则会生成一个正常连接,运行速度非常快:
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
?我在Yii2中有一个多对多关系:RecipeUnit-IngCrediteWeight-Component
您编写的,并且您的联接是简单的hasMany
关系,那么会有什么缺点吗。所以是的,当然会更快。同样,在第二种情况下,您使用的是limit1
,在第一种情况下,相同的查询get的2977
结果。做你的测试是正确的。有时,使用IN()
连接比加载记录更有效。我认为,如果两个模型(RecipeUnit和Component)之间存在切换模型(在本例中为IngredientWeight),则这是一种真实的N对N关系。通过
的方法正好实现了这一点。
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)