如何在Yii2 Kartik GridView中使用一个大查询而不是一个一个查询?

时间:2014-12-30 18:57:10

标签: performance gridview yii2

我希望有一个GridView来显示Yii2中多个表的数据。 仅举例来说,这是数据库结构的简化示例:

表1:条目

表2:名称

表3:NameOfSomething(name_id fk,entry_id fk)

表4:日期(entry_id fk)

表5:放置

表6:PlaceOfSomething(place_id fk,entry_id fk)

表7:PlaceOfSomethingElse(place_id fk,entry_id fk)

很多连接以及where子句。

如果我将ActiveRecord与Kartik GridView一起使用,它会逐行查询以连接其他表并将where子句放在一起。我需要显示至少500-1000个没有分页的结果行。有了这个,即使一个查询需要几毫秒,也需要10-100秒来检索我需要显示的所有数据。 我有一个与datatables.net的其他解决方案,我有一个大的查询,我给这个提供表。它的性能要好20到30倍,这就足够了。 所以问题是,有没有办法在Yii2中使用一个大查询而不是大量查询来提供GridView来提高性能 - 保持过滤器和排序功能?如果是,怎么样?

!! UPDATE !!

所以真正的问题是在第二级连接的表(如Place)。它仍在查询每一行。以下是我的代码示例:

class Entry
...
public function getPlaceOfSomething() {
    return $this->hasOne(PlaceOfSomething::className(), ['id' => 'plcofsthg_id']);
}
public function getPlace() {
    return $this->hasOne(PlaceOfSomething::className(), ['id' => 'plcofsthg_id'])->joinWith('place');
}
public function getPlaceOfSomethingName() {
    return $this->Place->getPlaceName();
}

class PlaceOfSomething
...
public function getPlace() {
    return $this->hasOne(Place::className(), ['id' => 'place_id']);
}
public function getPlaceName() {
    return $this->getPlace()->one()['name'];
}

class Place is in the generated way, contains id and name

从日志中

这可以获得1个查询中的所有内容(仍然分开,但没关系):

SELECT * FROM place WHERE id IN(' 1',' 2',' 3',' 29',' 25',' 85',' 5',' 27',' 30', ' 168',' 6',' 14',' 38',' 45',' 32& #39;,' 133',' 33',' 10',' 67',' 1057',& #39; 69',' 73',' 74',' 95',' 46',' 103&# 39;,' 107',' 108',' 101',' 52',' 42',&# 39; 308&#39)

然后再一次查询所有查询:

SELECT * FROM place WHERE id =' 33'

1 个答案:

答案 0 :(得分:0)

看看渴望加载与延迟加载,就像deacs告诉你的那样。这是官方链接:http://www.yiiframework.com/doc-2.0/guide-db-active-record.html#lazy-and-eager-loading

使用数据表您无法解决问题,您仍然需要加载所有数据,只有急切加载才能解决问题。你应该看到你的观点有了很大的改进。还可以使用调试工具栏确保正确实现它并观察查询数量是否会直线下降。