Skip to content

Commit

Permalink
Optimize count queries by removing all joins if there are no where cl…
Browse files Browse the repository at this point in the history
…auses using joined tables and all joins are left joins (#2210)
  • Loading branch information
colinmollenhour authored May 18, 2023
1 parent 12aab25 commit d6927f9
Showing 1 changed file with 25 additions and 0 deletions.
25 changes: 25 additions & 0 deletions lib/Varien/Data/Collection/Db.php
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,32 @@ public function getSelectCountSql()
$countSelect->columns("COUNT(DISTINCT " . implode(", ", $group) . ")");
} else {
$countSelect->columns('COUNT(*)');

// Simple optimization - remove all joins if there are no where clauses using joined tables and all joins are left joins
$leftJoins = array_filter($countSelect->getPart(Zend_Db_Select::FROM), function($table) {
return ($table['joinType'] == Zend_Db_Select::LEFT_JOIN || $table['joinType'] == Zend_Db_Select::FROM);
});
if (count($leftJoins) == count($countSelect->getPart(Zend_Db_Select::FROM))) {
$mainTable = array_filter($leftJoins, function ($table) {
return $table['joinType'] == Zend_Db_Select::FROM;
});
$mainTable = key($mainTable);
$mainTable = preg_quote($mainTable, '/');
$pattern = "/^$mainTable\\.\\w+/";
$whereUsingJoin = array_filter($countSelect->getPart(Zend_Db_Select::WHERE), function ($clause) use ($pattern) {
$clauses = preg_split('/(^|\s+)(AND|OR)\s+/', $clause, -1, PREG_SPLIT_NO_EMPTY);
return array_filter($clauses, function ($clause) use ($pattern) {
$clause = preg_replace('/[()`\s]+/', '', $clause);
return !preg_match($pattern, $clause);
});
});
if (empty($whereUsingJoin)) {
$from = array_slice($leftJoins, 0, 1);
$countSelect->setPart(Zend_Db_Select::FROM, $from);
}
}
}

return $countSelect;
}

Expand Down

0 comments on commit d6927f9

Please sign in to comment.