Skip to content

Commit

Permalink
[TASK] Speed up DB query for tables with versions
Browse files Browse the repository at this point in the history
Eliminating OR combination of subselects within same table, as they get
wrongly managed by DBMS (mostly MySQL). Using JOIN and UNION reduces
time to execute (on larger data sets) from 10 s to 0.01 s. This helps to
get the page tree view working if an editor is inside workspace.

Resolves: #86945
Releases: master, 9.5, 8.7
Change-Id: I7a5aa66baa6cef160de66fff3f80aec49b46295f
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/61604
Tested-by: TYPO3com <noreply@typo3.com>
Tested-by: Benni Mack <benni@typo3.org>
Reviewed-by: Benni Mack <benni@typo3.org>
  • Loading branch information
opi99 authored and bmack committed Sep 9, 2019
1 parent 79c9835 commit 0dab9b4
Showing 1 changed file with 17 additions and 26 deletions.
43 changes: 17 additions & 26 deletions typo3/sysext/workspaces/Classes/Service/WorkspaceService.php
Expand Up @@ -869,7 +869,8 @@ protected function fetchPagesWithVersionsInTable($workspaceId, $tableName)
if (!isset($this->pagesWithVersionsInTable[$workspaceId][$tableName])) {
$this->pagesWithVersionsInTable[$workspaceId][$tableName] = [];

$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($tableName);
$connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($tableName);
$queryBuilder = $connection->createQueryBuilder();
$queryBuilder->getRestrictions()
->removeAll()
->add(GeneralUtility::makeInstance(DeletedRestriction::class));
Expand All @@ -888,43 +889,33 @@ protected function fetchPagesWithVersionsInTable($workspaceId, $tableName)
);
// create sub-queries, parameters are available for main query
$versionQueryBuilder = $this->createQueryBuilderForTable($tableName)
->select('A.t3ver_oid')
->from($tableName, 'A')
->select('B.pid AS pageId')
->from($tableName, 'B')
->join('B', $tableName, 'A', $queryBuilder->expr()->eq('B.uid', $queryBuilder->quoteIdentifier('A.t3ver_oid')))
->where(
$queryBuilder->expr()->eq('A.pid', $pageIdParameter),
$queryBuilder->expr()->eq('A.t3ver_wsid', $workspaceIdParameter),
$queryBuilder->expr()->neq('A.t3ver_state', $movePointerParameter)
);
)
->groupBy('B.pid');
$movePointerQueryBuilder = $this->createQueryBuilderForTable($tableName)
->select('A.t3ver_oid')
->from($tableName, 'A')
->select('B.pid AS pageId')
->from($tableName, 'B')
->join('B', $tableName, 'A', $queryBuilder->expr()->eq('B.t3ver_move_id', $queryBuilder->quoteIdentifier('A.t3ver_oid')))
->where(
$queryBuilder->expr()->eq('A.pid', $pageIdParameter),
$queryBuilder->expr()->eq('A.t3ver_wsid', $workspaceIdParameter),
$queryBuilder->expr()->eq('A.t3ver_state', $movePointerParameter)
);
$subQuery = '%s IN (%s)';
// execute main query
$result = $queryBuilder
->select('B.pid AS pageId')
->from($tableName, 'B')
->orWhere(
sprintf(
$subQuery,
$queryBuilder->quoteIdentifier('B.uid'),
$versionQueryBuilder->getSQL()
),
sprintf(
$subQuery,
$queryBuilder->quoteIdentifier('B.t3ver_move_id'),
$movePointerQueryBuilder->getSQL()
)
)
->groupBy('B.pid')
->execute();
->groupBy('B.pid');
// execute main query
$result = $connection->executeQuery(
$versionQueryBuilder->getSQL() . ' UNION ' . $movePointerQueryBuilder->getSQL(),
$queryBuilder->getParameters()
);

$pageIds = [];
while ($row = $result->fetch()) {
while ($row = $result->fetch(\PDO::FETCH_ASSOC)) {
$pageIds[$row['pageId']] = true;
}

Expand Down

0 comments on commit 0dab9b4

Please sign in to comment.