TYPO3:分页的性能问题
TYPO3: Performance issue with pagination
我目前正在基于我创建的扩展程序构建某种视频频道。它由视频和包含视频的播放列表组成(很明显)。
我必须创建一个页面,其中包含按类别分类的视频列表和播放列表。您还可以按日期对这些项目进行排序。最后,页面被无限滚动分页,应该加载 21 x 21 项。
为此,我在视频和播放列表存储库上创建了一个非常简单的 "findByCategory" 函数:
$query = $this->createQuery();
return $query->matching($query->equals('categorie.uid',$categoryUid))->execute()->toArray();
一旦我请求了我需要的项目,我就将它们合并到一个数组中并进行排序。这是我的控制器显示动作:
if ($this->request->hasArgument('sort'))
$sort = $this->request->getArgument('sort');
else
$sort = 'antechrono';
//Get videos in repositories
$videos = $this->videoRepository->findByCategorie($categorie->getUid());
$playlists = $this->playlistRepository->findByCategorie($categorie->getUid());
//Merging arrays then sort it
if ($videos && $playlists)
$result = array_merge($videos, $playlists);
else if ($videos)
$result = $videos;
else if ($playlists)
$result = $playlists;
if ($sort == "chrono")
usort($result, array($this, "sortChrono"));
else if ($sort == "antechrono" || $sort == null)
{
usort($result, array($this, "sortAnteChrono"));
$sort="antechrono";
}
$this->view->assignMultiple(array('categorie' => $categorie, 'list' => $result, 'sort' => $sort));
这是我的观点:
<f:widget.paginate objects="{list}" as="paginatedList" configuration="{addQueryString: 'true', addQueryStringMethod: 'GET,POST', itemsPerPage: 21}">
<div class="videos row">
<f:for each="{paginatedList}" as="element">
<f:render partial="Show/ItemCat" arguments="{item: element}"/>
</f:for>
</div>
</f:widget.paginate>
部分渲染显示了一些东西,包括用作封面的图片。所以我在视图中至少需要这种关系。
这工作正常并且只显示请求类别中的项目。不幸的是,我遇到了一个巨大的性能问题:我试图显示一个包含 3000 多条记录的类别,加载大约需要一分钟。它有 一点 长。
通过 f:debugging 我的列表变量,我看到它包含每条记录,即使它不应该是这种情况(这就是分页点...)。所以第一个问题是:我的分页方式有问题吗?
我试图通过启用 rawQuery 东西($query->execute(true))来简化我的请求:我获得了更好的性能,但我无法获得图片的 link(在在我看来,我得到 1 或 0 但不是图片的 uid ...)。第二个问题:有没有办法解决这个问题?
希望我的描述足够清楚。感谢您的帮助:-)
当您执行查询时,在访问结果之前,它不会真正从数据库中获取数据。如果分页小部件获得查询结果,它将为查询添加限制和偏移量,然后从数据库中获取数据,因此您只会获得页面上显示的记录。
在您的情况下,您在 execute()
之后添加了 toArray()
,这会访问结果,因此数据是从数据库中获取的,您会获得所有记录。我能想到的最佳解决方案是将 2 个表合并为 1 个,这样您就可以通过单个查询来完成,而不必在 PHP.
中合并和排序它们
只要在查询后对数据进行排序,就必须处理所有数据(请求所有记录,尤其是解决所有关系)。
尝试在查询本身中对数据进行排序 (order by
),这样您就可以将数据限制为仅当前 'page' (limit <offset>,<number>
) 所需的那些记录.
这里使用 join
和 limit
的复杂查询可能比 PHP.
中的完整查询和过滤更快
我目前正在基于我创建的扩展程序构建某种视频频道。它由视频和包含视频的播放列表组成(很明显)。 我必须创建一个页面,其中包含按类别分类的视频列表和播放列表。您还可以按日期对这些项目进行排序。最后,页面被无限滚动分页,应该加载 21 x 21 项。 为此,我在视频和播放列表存储库上创建了一个非常简单的 "findByCategory" 函数:
$query = $this->createQuery();
return $query->matching($query->equals('categorie.uid',$categoryUid))->execute()->toArray();
一旦我请求了我需要的项目,我就将它们合并到一个数组中并进行排序。这是我的控制器显示动作:
if ($this->request->hasArgument('sort'))
$sort = $this->request->getArgument('sort');
else
$sort = 'antechrono';
//Get videos in repositories
$videos = $this->videoRepository->findByCategorie($categorie->getUid());
$playlists = $this->playlistRepository->findByCategorie($categorie->getUid());
//Merging arrays then sort it
if ($videos && $playlists)
$result = array_merge($videos, $playlists);
else if ($videos)
$result = $videos;
else if ($playlists)
$result = $playlists;
if ($sort == "chrono")
usort($result, array($this, "sortChrono"));
else if ($sort == "antechrono" || $sort == null)
{
usort($result, array($this, "sortAnteChrono"));
$sort="antechrono";
}
$this->view->assignMultiple(array('categorie' => $categorie, 'list' => $result, 'sort' => $sort));
这是我的观点:
<f:widget.paginate objects="{list}" as="paginatedList" configuration="{addQueryString: 'true', addQueryStringMethod: 'GET,POST', itemsPerPage: 21}">
<div class="videos row">
<f:for each="{paginatedList}" as="element">
<f:render partial="Show/ItemCat" arguments="{item: element}"/>
</f:for>
</div>
</f:widget.paginate>
部分渲染显示了一些东西,包括用作封面的图片。所以我在视图中至少需要这种关系。
这工作正常并且只显示请求类别中的项目。不幸的是,我遇到了一个巨大的性能问题:我试图显示一个包含 3000 多条记录的类别,加载大约需要一分钟。它有 一点 长。
通过 f:debugging 我的列表变量,我看到它包含每条记录,即使它不应该是这种情况(这就是分页点...)。所以第一个问题是:我的分页方式有问题吗?
我试图通过启用 rawQuery 东西($query->execute(true))来简化我的请求:我获得了更好的性能,但我无法获得图片的 link(在在我看来,我得到 1 或 0 但不是图片的 uid ...)。第二个问题:有没有办法解决这个问题?
希望我的描述足够清楚。感谢您的帮助:-)
当您执行查询时,在访问结果之前,它不会真正从数据库中获取数据。如果分页小部件获得查询结果,它将为查询添加限制和偏移量,然后从数据库中获取数据,因此您只会获得页面上显示的记录。
在您的情况下,您在 execute()
之后添加了 toArray()
,这会访问结果,因此数据是从数据库中获取的,您会获得所有记录。我能想到的最佳解决方案是将 2 个表合并为 1 个,这样您就可以通过单个查询来完成,而不必在 PHP.
只要在查询后对数据进行排序,就必须处理所有数据(请求所有记录,尤其是解决所有关系)。
尝试在查询本身中对数据进行排序 (order by
),这样您就可以将数据限制为仅当前 'page' (limit <offset>,<number>
) 所需的那些记录.
这里使用 join
和 limit
的复杂查询可能比 PHP.