[英]Performance improvement - Yii2 Eager loading
We have a table called content and size of table is over 5Gb.我们有一个名为 content 的表,表的大小超过 5Gb。 Our Yii2 backend application has a section to view those content and there are few filters available to filter out contents.
我们的 Yii2 后端应用程序有一个部分可以查看这些内容,并且几乎没有过滤器可用于过滤掉内容。 I need to filter contents which are assigned or not assigned to categories.
我需要过滤已分配或未分配给类别的内容。
Relations关系
A Content can be shared within many categories.内容可以在许多类别中共享。 So there is a one to many relationship between Content and Category tables.
因此 Content 和 Category 表之间存在一对多的关系。
Mapping table is content_cat_xref.映射表是 content_cat_xref。
Models are as follows.型号如下。
Content model内容 model
/**
* @return \yii\db\ActiveQuery
*/
public function getContentCatXrefs()
{
return $this->hasMany(ContentCatXref::className(), ['content_id' => 'id']);
}
Content_cat_xref model Content_cat_xref model
/**
* @return \yii\db\ActiveQuery
*/
public function getCategory()
{
return $this->hasOne(Category::className(), ['id' => 'category_id']);
}
/**
* @return \yii\db\ActiveQuery
*/
public function getContent()
{
return $this->hasOne(Content::className(), ['id' => 'content_id']);
}
Controller Controller
public function actionIndex()
{
$searchModel = new \common\models\ContentSearch();
$dataProvider = $searchModel->searchMedia(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider
]);
}
ContentSearch Model内容搜索 Model
public function searchMedia($params)
{
$query = Content::find()->where(['file_type_id'=>[1,2,3,4,5,6,8,11]]);
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$this->load($params);
if (!$this->validate()) {
return $dataProvider;
}
//Conditionally add filters
if(isset($this->is_category_available) && $this->is_category_available === 'yes'){
$query = $query->joinWith(['contentCatXrefs' => function($queryw){
$queryw->andWhere(['is not', 'content_cat_xref.category_id', new \yii\db\Expression('null')]);
}]);
}else if(isset($this->is_category_available) && $this->is_category_available === 'no'){
$query = $query->joinWith(['contentCatXrefs' => function($queryw){
$queryw->andWhere(['is', 'content_cat_xref.category_id', new \yii\db\Expression('null')]);
}]);
}
if(!is_null($this->file_name) && !empty($this->file_name)) {
$query->andWhere("MATCH (file_name) AGAINST (\"".$this->file_name."\" IN NATURAL LANGUAGE MODE)");
}
if(!is_null($this->file_path) && !empty($this->file_path)) {
$query->andWhere("MATCH (file_path) AGAINST (\"".$this->file_path."\" IN NATURAL LANGUAGE MODE)");
}
$query->andFilterWhere(['type_code'=>$this->type_code]);
$query->andFilterWhere(['file_type_id'=>$this->file_type_id]);
$query->andFilterWhere(['content.active_status'=>$this->active_status]);
$query->andFilterWhere(['content.content_status'=>$this->content_status]);
if(is_null($this->file_name)) {
$query->orderBy("id desc");
}
return $dataProvider;
}
I have few questions我有几个问题
What should be the correct and efficient way to join two tables( content and content_cat_xref) to retrieve data.连接两个表(content 和 content_cat_xref)以检索数据的正确有效方法应该是什么。 I need to filter contents which are assigned or not assigned to categories.
我需要过滤已分配或未分配给类别的内容。 So, I use this filter for that.
所以,我为此使用了这个过滤器。
if(isset($this->is_category_available) && $this->is_category_available === 'yes'){ $query = $query->joinWith(['contentCatXrefs' => function($queryw){ $queryw->andWhere(['is not', 'content_cat_xref.category_id', new \yii\db\Expression('null')]); }]); }else if(isset($this->is_category_available) && $this->is_category_available === 'no'){ $query = $query->joinWith(['contentCatXrefs' => function($queryw){ $queryw->andWhere(['is', 'content_cat_xref.category_id', new \yii\db\Expression('null')]); }]); }
I use eager loading to improve performance here.我在这里使用急切加载来提高性能。 But It gives duplicate records when joining these two tables.
但是在加入这两个表时它会给出重复的记录。 After I use distinct then it reduce the performance.
在我使用 distinct 之后,它会降低性能。 What should be the correct way to do this Yii2?
执行此 Yii2 的正确方法应该是什么?
Is there are way to pass params to relation functions when constructing query in content search model?在内容搜索 model 中构造查询时,有没有办法将参数传递给关系函数?
If we order content by id descending, again reduce the performance.如果我们按 id 降序排列内容,再次降低性能。
It is highly appreciated if there is anyone who can provide guidance on this.如果有人可以提供这方面的指导,我们将不胜感激。
if($this->is_category_available == 'yes') { return $this->hasMany(ContentCatXref::className(), ['content_id' => 'id']) ->andOnCondition(['a_type' => 1]); } else { return $this->hasMany(ContentCatXref::className(), ['content_id' => 'id']) ->andOnCondition(['a_type' => 0]); }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.