|
11 | 11 | use Magento\Framework\App\Config\ScopeConfigInterface; |
12 | 12 | use Magento\Framework\DB\Select; |
13 | 13 | use Magento\Store\Model\ScopeInterface; |
| 14 | +use Magento\Framework\DB\Adapter\AdapterInterface; |
| 15 | +use Magento\Framework\DB\Ddl\Table; |
14 | 16 |
|
15 | 17 | /** |
16 | 18 | * Category resource collection |
@@ -370,40 +372,80 @@ public function loadProductCount($items, $countRegular = true, $countAnchor = tr |
370 | 372 | * @param array $categoryIds |
371 | 373 | * @param int $websiteId |
372 | 374 | * @return array |
| 375 | + * @throws \Zend_Db_Exception |
373 | 376 | */ |
374 | 377 | private function getCountFromCategoryTableBulk( |
375 | 378 | array $categoryIds, |
376 | 379 | int $websiteId |
377 | 380 | ) : array { |
378 | | - $subSelect = clone $this->_conn->select(); |
379 | | - $subSelect->from(['ce2' => $this->getTable('catalog_category_entity')], 'ce2.entity_id') |
380 | | - ->where("ce2.path LIKE CONCAT(ce.path, '/%') OR ce2.path = ce.path"); |
381 | | - |
382 | | - $select = clone $this->_conn->select(); |
383 | | - $select->from( |
384 | | - ['ce' => $this->getTable('catalog_category_entity')], |
385 | | - 'ce.entity_id' |
386 | | - ); |
387 | | - $joinCondition = new \Zend_Db_Expr("cp.category_id IN ({$subSelect})"); |
388 | | - $select->joinLeft( |
389 | | - ['cp' => $this->getProductTable()], |
390 | | - $joinCondition, |
391 | | - 'COUNT(DISTINCT cp.product_id) AS product_count' |
| 381 | + $connection = $this->_conn; |
| 382 | + $tempTableName = 'temp_category_descendants_' . uniqid(); |
| 383 | + $tempTable = $connection->newTable($tempTableName) |
| 384 | + ->addColumn( |
| 385 | + 'category_id', |
| 386 | + Table::TYPE_INTEGER, |
| 387 | + null, |
| 388 | + ['unsigned' => true, 'nullable' => false], |
| 389 | + 'Category ID' |
| 390 | + ) |
| 391 | + ->addColumn( |
| 392 | + 'descendant_id', |
| 393 | + Table::TYPE_INTEGER, |
| 394 | + null, |
| 395 | + ['unsigned' => true, 'nullable' => false], |
| 396 | + 'Descendant ID' |
| 397 | + ) |
| 398 | + ->addIndex( |
| 399 | + $connection->getIndexName($tempTableName, ['category_id', 'descendant_id']), |
| 400 | + ['category_id', 'descendant_id'], |
| 401 | + ['type' => AdapterInterface::INDEX_TYPE_PRIMARY] |
| 402 | + ); |
| 403 | + $connection->createTemporaryTable($tempTable); |
| 404 | + $selectDescendants = $connection->select() |
| 405 | + ->from( |
| 406 | + ['ce' => $this->getTable('catalog_category_entity')], |
| 407 | + ['category_id' => 'ce.entity_id', 'descendant_id' => 'ce2.entity_id'] |
| 408 | + ) |
| 409 | + ->joinInner( |
| 410 | + ['ce2' => $this->getTable('catalog_category_entity')], |
| 411 | + 'ce2.path LIKE CONCAT(ce.path, \'/%\') OR ce2.entity_id = ce.entity_id', |
| 412 | + [] |
| 413 | + ) |
| 414 | + ->where('ce.entity_id IN (?)', $categoryIds); |
| 415 | + |
| 416 | + $connection->query( |
| 417 | + $connection->insertFromSelect( |
| 418 | + $selectDescendants, |
| 419 | + $tempTableName, |
| 420 | + ['category_id', 'descendant_id'] |
| 421 | + ) |
392 | 422 | ); |
| 423 | + $select = $connection->select() |
| 424 | + ->from( |
| 425 | + ['t' => $tempTableName], |
| 426 | + ['category_id' => 't.category_id'] |
| 427 | + ) |
| 428 | + ->joinLeft( |
| 429 | + ['cp' => $this->getTable('catalog_category_product')], |
| 430 | + 'cp.category_id = t.descendant_id', |
| 431 | + ['product_count' => 'COUNT(DISTINCT cp.product_id)'] |
| 432 | + ); |
393 | 433 | if ($websiteId) { |
394 | 434 | $select->join( |
395 | 435 | ['w' => $this->getProductWebsiteTable()], |
396 | 436 | 'cp.product_id = w.product_id', |
397 | 437 | [] |
398 | | - )->where( |
399 | | - 'w.website_id = ?', |
400 | | - $websiteId |
401 | | - ); |
| 438 | + )->where('w.website_id = ?', $websiteId); |
| 439 | + } |
| 440 | + $select->group('t.category_id'); |
| 441 | + $result = $connection->fetchPairs($select); |
| 442 | + $connection->dropTemporaryTable($tempTableName); |
| 443 | + $counts = array_fill_keys($categoryIds, 0); |
| 444 | + foreach ($result as $categoryId => $count) { |
| 445 | + $counts[$categoryId] = (int)$count; |
402 | 446 | } |
403 | | - $select->where('ce.entity_id IN(?)', $categoryIds); |
404 | | - $select->group('ce.entity_id'); |
405 | 447 |
|
406 | | - return $this->_conn->fetchPairs($select); |
| 448 | + return $counts; |
407 | 449 | } |
408 | 450 |
|
409 | 451 | /** |
|
0 commit comments