From d6927f9911566c3571e89414ae2693a5cece8d71 Mon Sep 17 00:00:00 2001 From: Colin Mollenhour Date: Thu, 18 May 2023 17:16:01 -0400 Subject: [PATCH] Optimize count queries by removing all joins if there are no where clauses using joined tables and all joins are left joins (#2210) --- lib/Varien/Data/Collection/Db.php | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/lib/Varien/Data/Collection/Db.php b/lib/Varien/Data/Collection/Db.php index 75d3fbc91e6..1126bed1297 100644 --- a/lib/Varien/Data/Collection/Db.php +++ b/lib/Varien/Data/Collection/Db.php @@ -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; }