Yii2 hasMany/via vs. hasMany/viaTable vs. find/joinWith

孤者浪人 提交于 2019-12-08 10:50:29

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!