diff --git a/vendor/magento/module-catalog/Model/ResourceModel/Category/Collection.php b/vendor/magento/module-catalog/Model/ResourceModel/Category/Collection.php
index 259399ece827b..e6d3c5880c858 100644
--- a/vendor/magento/module-catalog/Model/ResourceModel/Category/Collection.php
+++ b/vendor/magento/module-catalog/Model/ResourceModel/Category/Collection.php
@@ -1,7 +1,7 @@
 <?php
 /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
+ * Copyright 2011 Adobe
+ * All Rights Reserved.
  */
 namespace Magento\Catalog\Model\ResourceModel\Category;
 
@@ -21,6 +21,8 @@
  */
 class Collection extends \Magento\Catalog\Model\ResourceModel\Collection\AbstractCollection
 {
+    private const BULK_PROCESSING_LIMIT = 400;
+
     /**
      * Event prefix name
      *
@@ -282,6 +284,7 @@ protected function _loadProductCount()
      * @return $this
      * @SuppressWarnings(PHPMD.CyclomaticComplexity)
      * @SuppressWarnings(PHPMD.UnusedLocalVariable)
+     * @SuppressWarnings(PHPMD.NPathComplexity)
      * @throws \Magento\Framework\Exception\NoSuchEntityException
      */
     public function loadProductCount($items, $countRegular = true, $countAnchor = true)
@@ -337,16 +340,111 @@ public function loadProductCount($items, $countRegular = true, $countAnchor = tr
             $categoryIds = array_keys($anchor);
             $countSelect = $this->getProductsCountQuery($categoryIds, (bool)$websiteId);
             $categoryProductsCount = $this->_conn->fetchPairs($countSelect);
+            $countFromCategoryTable = [];
+            if (count($categoryIds) > self::BULK_PROCESSING_LIMIT) {
+                $countFromCategoryTable = $this->getCountFromCategoryTableBulk($categoryIds, (int)$websiteId);
+            }
+
             foreach ($anchor as $item) {
-                $productsCount = isset($categoryProductsCount[$item->getId()])
-                    ? (int)$categoryProductsCount[$item->getId()]
-                    : $this->getProductsCountFromCategoryTable($item, $websiteId);
+                $productsCount = 0;
+                if (count($categoryIds) > self::BULK_PROCESSING_LIMIT) {
+                    if (isset($categoryProductsCount[$item->getId()])) {
+                        $productsCount = (int)$categoryProductsCount[$item->getId()];
+                    } elseif (isset($countFromCategoryTable[$item->getId()])) {
+                        $productsCount = (int)$countFromCategoryTable[$item->getId()];
+                    }
+                } else {
+                    $productsCount = isset($categoryProductsCount[$item->getId()])
+                        ? (int)$categoryProductsCount[$item->getId()]
+                        : $this->getProductsCountFromCategoryTable($item, $websiteId);
+                }
                 $item->setProductCount($productsCount);
             }
         }
         return $this;
     }
 
+    /**
+     * Get products number for each category with bulk query
+     *
+     * @param array $categoryIds
+     * @param int $websiteId
+     * @return array
+     */
+    private function getCountFromCategoryTableBulk(
+        array $categoryIds,
+        int $websiteId
+    ) : array {
+        $subSelect = clone $this->_conn->select();
+        $subSelect->from(['ce2' => $this->getTable('catalog_category_entity')], 'ce2.entity_id')
+            ->where("ce2.path LIKE CONCAT(ce.path, '/%') OR ce2.path = ce.path");
+
+        $select = clone $this->_conn->select();
+        $select->from(
+            ['ce' => $this->getTable('catalog_category_entity')],
+            'ce.entity_id'
+        );
+        $joinCondition =  new \Zend_Db_Expr("cp.category_id IN ({$subSelect})");
+        $select->joinLeft(
+            ['cp' => $this->getProductTable()],
+            $joinCondition,
+            'COUNT(DISTINCT cp.product_id) AS product_count'
+        );
+        if ($websiteId) {
+            $select->join(
+                ['w' => $this->getProductWebsiteTable()],
+                'cp.product_id = w.product_id',
+                []
+            )->where(
+                'w.website_id = ?',
+                $websiteId
+            );
+        }
+        $select->where('ce.entity_id IN(?)', $categoryIds);
+        $select->group('ce.entity_id');
+
+        return $this->_conn->fetchPairs($select);
+    }
+
+    /**
+     * Get products count using catalog_category_entity table
+     *
+     * @param Category $item
+     * @param string $websiteId
+     * @return int
+     */
+    private function getProductsCountFromCategoryTable(Category $item, string $websiteId): int
+    {
+        $productCount = 0;
+
+        if ($item->getAllChildren()) {
+            $bind = ['entity_id' => $item->getId(), 'c_path' => $item->getPath() . '/%'];
+            $select = $this->_conn->select();
+            $select->from(
+                ['main_table' => $this->getProductTable()],
+                new \Zend_Db_Expr('COUNT(DISTINCT main_table.product_id)')
+            )->joinInner(
+                ['e' => $this->getTable('catalog_category_entity')],
+                'main_table.category_id=e.entity_id',
+                []
+            )->where(
+                '(e.entity_id = :entity_id OR e.path LIKE :c_path)'
+            );
+            if ($websiteId) {
+                $select->join(
+                    ['w' => $this->getProductWebsiteTable()],
+                    'main_table.product_id = w.product_id',
+                    []
+                )->where(
+                    'w.website_id = ?',
+                    $websiteId
+                );
+            }
+            $productCount = (int)$this->_conn->fetchOne($select, $bind);
+        }
+        return $productCount;
+    }
+
     /**
      * Add category path filter
      *
@@ -519,45 +617,6 @@ public function getProductTable()
         return $this->_productTable;
     }
 
-    /**
-     * Get products count using catalog_category_entity table
-     *
-     * @param Category $item
-     * @param string $websiteId
-     * @return int
-     */
-    private function getProductsCountFromCategoryTable(Category $item, string $websiteId): int
-    {
-        $productCount = 0;
-
-        if ($item->getAllChildren()) {
-            $bind = ['entity_id' => $item->getId(), 'c_path' => $item->getPath() . '/%'];
-            $select = $this->_conn->select();
-            $select->from(
-                ['main_table' => $this->getProductTable()],
-                new \Zend_Db_Expr('COUNT(DISTINCT main_table.product_id)')
-            )->joinInner(
-                ['e' => $this->getTable('catalog_category_entity')],
-                'main_table.category_id=e.entity_id',
-                []
-            )->where(
-                '(e.entity_id = :entity_id OR e.path LIKE :c_path)'
-            );
-            if ($websiteId) {
-                $select->join(
-                    ['w' => $this->getProductWebsiteTable()],
-                    'main_table.product_id = w.product_id',
-                    []
-                )->where(
-                    'w.website_id = ?',
-                    $websiteId
-                );
-            }
-            $productCount = (int)$this->_conn->fetchOne($select, $bind);
-        }
-        return $productCount;
-    }
-
     /**
      * Get query for retrieve count of products per category
      *
