问题
I have a many to many relation in Yii2: RecipeUnit - IngredientWeight - Ingredient. In model 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');
}
Using the following code ActiveQuery generates two SQLs instead of one join, and it takes long time ($model
is a RecipeUnit instance with id
= 4):
$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)
The result is the same if I'm using hasMany
/viaTable
instead hasMany
/via
:
public function getIngredients()
{
return $this->hasMany(Ingredient::className(), ['id' => 'ingredient_id'])
->viaTable(IngredientWeight::tableName(), ['recipe_unit_id' => 'id']);
}
But without hasMany a normal join is generated, running very quickly:
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)
The question is, is there any disadvantage if the relation is defined as in the last example without hasMany
/via
?
来源:https://stackoverflow.com/questions/35131847/yii2-hasmany-via-vs-hasmany-viatable-vs-find-joinwith