|
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