diff --git a/vendor/magento/module-sales/Model/ResourceModel/Report/Bestsellers.php b/vendor/magento/module-sales/Model/ResourceModel/Report/Bestsellers.php
index e37e8ab843e..a4d2d3cbb94 100644
--- a/vendor/magento/module-sales/Model/ResourceModel/Report/Bestsellers.php
+++ b/vendor/magento/module-sales/Model/ResourceModel/Report/Bestsellers.php
@@ -5,25 +5,39 @@
  */
 namespace Magento\Sales\Model\ResourceModel\Report;

+use Magento\Catalog\Model\ResourceModel\Product;
+use Magento\Framework\App\ObjectManager;
+use Magento\Framework\DB\Select;
+use Magento\Framework\Exception\LocalizedException;
+use Magento\Framework\Model\ResourceModel\Db\Context;
+use Magento\Framework\Stdlib\DateTime\DateTime;
+use Magento\Framework\Stdlib\DateTime\Timezone\Validator;
+use Magento\Framework\Stdlib\DateTime\TimezoneInterface;
+use Magento\Reports\Model\FlagFactory;
+use Magento\Sales\Model\ResourceModel\Helper;
+use Magento\Store\Model\Store;
+use Magento\Store\Model\StoreManagerInterface;
+use Psr\Log\LoggerInterface;
+
 /**
  * Bestsellers report resource model
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
 class Bestsellers extends AbstractReport
 {
-    const AGGREGATION_DAILY = 'daily';
+    public const AGGREGATION_DAILY = 'daily';

-    const AGGREGATION_MONTHLY = 'monthly';
+    public const AGGREGATION_MONTHLY = 'monthly';

-    const AGGREGATION_YEARLY = 'yearly';
+    public const AGGREGATION_YEARLY = 'yearly';

     /**
-     * @var \Magento\Catalog\Model\ResourceModel\Product
+     * @var Product
      */
     protected $_productResource;

     /**
-     * @var \Magento\Sales\Model\ResourceModel\Helper
+     * @var Helper
      */
     protected $_salesResourceHelper;

@@ -37,29 +51,36 @@ class Bestsellers extends AbstractReport
     ];

     /**
-     * @param \Magento\Framework\Model\ResourceModel\Db\Context $context
-     * @param \Psr\Log\LoggerInterface $logger
-     * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
-     * @param \Magento\Reports\Model\FlagFactory $reportsFlagFactory
-     * @param \Magento\Framework\Stdlib\DateTime\Timezone\Validator $timezoneValidator
-     * @param \Magento\Framework\Stdlib\DateTime\DateTime $dateTime
-     * @param \Magento\Catalog\Model\ResourceModel\Product $productResource
-     * @param \Magento\Sales\Model\ResourceModel\Helper $salesResourceHelper
+     * @var StoreManagerInterface
+     */
+    protected $storeManager;
+
+    /**
+     * @param Context $context
+     * @param LoggerInterface $logger
+     * @param TimezoneInterface $localeDate
+     * @param FlagFactory $reportsFlagFactory
+     * @param Validator $timezoneValidator
+     * @param DateTime $dateTime
+     * @param Product $productResource
+     * @param Helper $salesResourceHelper
+     * @param string|null $connectionName
      * @param array $ignoredProductTypes
-     * @param string $connectionName
+     * @param StoreManagerInterface|null $storeManager
      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
      */
     public function __construct(
-        \Magento\Framework\Model\ResourceModel\Db\Context $context,
-        \Psr\Log\LoggerInterface $logger,
-        \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
-        \Magento\Reports\Model\FlagFactory $reportsFlagFactory,
-        \Magento\Framework\Stdlib\DateTime\Timezone\Validator $timezoneValidator,
-        \Magento\Framework\Stdlib\DateTime\DateTime $dateTime,
-        \Magento\Catalog\Model\ResourceModel\Product $productResource,
-        \Magento\Sales\Model\ResourceModel\Helper $salesResourceHelper,
-        $connectionName = null,
-        array $ignoredProductTypes = []
+        Context $context,
+        LoggerInterface $logger,
+        TimezoneInterface $localeDate,
+        FlagFactory $reportsFlagFactory,
+        Validator $timezoneValidator,
+        DateTime $dateTime,
+        Product $productResource,
+        Helper $salesResourceHelper,
+        ?string $connectionName = null,
+        array $ignoredProductTypes = [],
+        ?StoreManagerInterface $storeManager = null
     ) {
         parent::__construct(
             $context,
@@ -73,6 +94,7 @@ class Bestsellers extends AbstractReport
         $this->_productResource = $productResource;
         $this->_salesResourceHelper = $salesResourceHelper;
         $this->ignoredProductTypes = array_merge($this->ignoredProductTypes, $ignoredProductTypes);
+        $this->storeManager = $storeManager ?: ObjectManager::getInstance()->get(StoreManagerInterface::class);
     }

     /**
@@ -92,123 +114,162 @@ class Bestsellers extends AbstractReport
      * @param string|int|\DateTime|array|null $to
      * @return $this
      * @throws \Exception
-     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
      */
     public function aggregate($from = null, $to = null)
     {
         $connection = $this->getConnection();
-        //$this->getConnection()->beginTransaction();
-
-        try {
-            if ($from !== null || $to !== null) {
-                $subSelect = $this->_getTableDateRangeSelect(
-                    $this->getTable('sales_order'),
-                    'created_at',
-                    'updated_at',
-                    $from,
-                    $to
-                );
-            } else {
-                $subSelect = null;
-            }
-
-            $this->_clearTableByDateRange($this->getMainTable(), $from, $to, $subSelect);
-            // convert dates to current admin timezone
-            $periodExpr = $connection->getDatePartSql(
-                $this->getStoreTZOffsetQuery(
-                    ['source_table' => $this->getTable('sales_order')],
-                    'source_table.created_at',
-                    $from,
-                    $to
-                )
-            );
-            $select = $connection->select();
-
-            $select->group([$periodExpr, 'source_table.store_id', 'order_item.product_id']);
-
-            $columns = [
-                'period' => $periodExpr,
-                'store_id' => 'source_table.store_id',
-                'product_id' => 'order_item.product_id',
-                'product_name' => new \Zend_Db_Expr('MIN(order_item.name)'),
-                'product_price' => new \Zend_Db_Expr(
-                    'MIN(IF(order_item_parent.base_price, order_item_parent.base_price, order_item.base_price))' .
-                    '* MIN(source_table.base_to_global_rate)'
-                ),
-                'qty_ordered' => new \Zend_Db_Expr('SUM(order_item.qty_ordered)'),
-            ];
-
-            $select->from(
-                ['source_table' => $this->getTable('sales_order')],
-                $columns
-            )->joinInner(
-                ['order_item' => $this->getTable('sales_order_item')],
-                'order_item.order_id = source_table.entity_id',
-                []
-            )->joinLeft(
-                ['order_item_parent' => $this->getTable('sales_order_item')],
-                'order_item.parent_item_id = order_item_parent.item_id',
-                []
-            )->where(
-                'source_table.state != ?',
-                \Magento\Sales\Model\Order::STATE_CANCELED
-            )->where(
-                'order_item.product_type NOT IN(?)',
-                $this->ignoredProductTypes
-            );
+        $this->clearByDateRange($from, $to);
+        foreach ($this->storeManager->getStores(true) as $store) {
+            $this->processStoreAggregate($store->getId(), $from, $to);
+        }

-            if ($subSelect !== null) {
-                $select->having($this->_makeConditionFromDateRangeSelect($subSelect, 'period'));
-            }
-
-            $select->useStraightJoin();
-            // important!
-            $insertQuery = $select->insertFromSelect($this->getMainTable(), array_keys($columns));
-            $connection->query($insertQuery);
-
-            $columns = [
-                'period' => 'period',
-                'store_id' => new \Zend_Db_Expr(\Magento\Store\Model\Store::DEFAULT_STORE_ID),
-                'product_id' => 'product_id',
-                'product_name' => new \Zend_Db_Expr('MIN(product_name)'),
-                'product_price' => new \Zend_Db_Expr('MIN(product_price)'),
-                'qty_ordered' => new \Zend_Db_Expr('SUM(qty_ordered)'),
-            ];
-
-            $select->reset();
-            $select->from(
-                $this->getMainTable(),
-                $columns
-            )->where(
-                'store_id <> ?',
-                \Magento\Store\Model\Store::DEFAULT_STORE_ID
-            );
+        $columns = [
+            'period' => 'period',
+            'store_id' => new \Zend_Db_Expr(Store::DEFAULT_STORE_ID),
+            'product_id' => 'product_id',
+            'product_name' => new \Zend_Db_Expr('MIN(product_name)'),
+            'product_price' => new \Zend_Db_Expr('MIN(product_price)'),
+            'qty_ordered' => new \Zend_Db_Expr('SUM(qty_ordered)'),
+        ];

-            if ($subSelect !== null) {
-                $select->where($this->_makeConditionFromDateRangeSelect($subSelect, 'period'));
-            }
-
-            $select->group(['period', 'product_id']);
-            $insertQuery = $select->insertFromSelect($this->getMainTable(), array_keys($columns));
-            $connection->query($insertQuery);
-
-            // update rating
-            $this->_updateRatingPos(self::AGGREGATION_DAILY);
-            $this->_updateRatingPos(self::AGGREGATION_MONTHLY);
-            $this->_updateRatingPos(self::AGGREGATION_YEARLY);
-            $this->_setFlagData(\Magento\Reports\Model\Flag::REPORT_BESTSELLERS_FLAG_CODE);
-        } catch (\Exception $e) {
-            throw $e;
+        $select = $connection->select();
+        $select->reset();
+        $select->from(
+            $this->getMainTable(),
+            $columns
+        )->where(
+            'store_id <> ?',
+            Store::DEFAULT_STORE_ID
+        );
+        $subSelect = $this->getRangeSubSelect($from, $to);
+        if ($subSelect !== null) {
+            $select->where($this->_makeConditionFromDateRangeSelect($subSelect, 'period'));
         }

+        $select->group(['period', 'product_id']);
+        $insertQuery = $select->insertFromSelect($this->getMainTable(), array_keys($columns));
+        $connection->query($insertQuery);
+
+        $this->_updateRatingPos(self::AGGREGATION_DAILY);
+        $this->_updateRatingPos(self::AGGREGATION_MONTHLY);
+        $this->_updateRatingPos(self::AGGREGATION_YEARLY);
+        $this->_setFlagData(\Magento\Reports\Model\Flag::REPORT_BESTSELLERS_FLAG_CODE);
+
         return $this;
     }

+    /**
+     * Clear aggregate existing data by range
+     *
+     * @param string|int|\DateTime|array|null $from
+     * @param string|int|\DateTime|array|null $to
+     * @return void
+     * @throws LocalizedException
+     */
+    private function clearByDateRange($from = null, $to = null): void
+    {
+        $subSelect = $this->getRangeSubSelect($from, $to);
+        $this->_clearTableByDateRange($this->getMainTable(), $from, $to, $subSelect);
+    }
+
+    /**
+     * Get report range sub-select
+     *
+     * @param string|int|\DateTime|array|null $from
+     * @param string|int|\DateTime|array|null $to
+     * @return Select|null
+     */
+    private function getRangeSubSelect($from = null, $to = null): ?Select
+    {
+        if ($from !== null || $to !== null) {
+            $subSelect = $this->_getTableDateRangeSelect(
+                $this->getTable('sales_order'),
+                'created_at',
+                'updated_at',
+                $from,
+                $to
+            );
+        } else {
+            $subSelect = null;
+        }
+
+        return $subSelect;
+    }
+
+    /**
+     * Calculate report aggregate per store
+     *
+     * @param int|null $storeId
+     * @param string|int|\DateTime|array|null $from
+     * @param string|int|\DateTime|array|null $to
+     * @return void
+     * @throws LocalizedException
+     */
+    private function processStoreAggregate(?int $storeId, $from = null, $to = null): void
+    {
+        $connection = $this->getConnection();
+
+        // convert dates to current admin timezone
+        $periodExpr = $connection->getDatePartSql(
+            $this->getStoreTZOffsetQuery(
+                ['source_table' => $this->getTable('sales_order')],
+                'source_table.created_at',
+                $from,
+                $to
+            )
+        );
+        $select = $connection->select();
+        $subSelect = $this->getRangeSubSelect($from, $to);
+
+        $select->group([$periodExpr, 'source_table.store_id', 'order_item.product_id']);
+
+        $columns = [
+            'period' => $periodExpr,
+            'store_id' => 'source_table.store_id',
+            'product_id' => 'order_item.product_id',
+            'product_name' => new \Zend_Db_Expr('MIN(order_item.name)'),
+            'product_price' => new \Zend_Db_Expr(
+                'MIN(IF(order_item_parent.base_price, order_item_parent.base_price, order_item.base_price))' .
+                '* MIN(source_table.base_to_global_rate)'
+            ),
+            'qty_ordered' => new \Zend_Db_Expr('SUM(order_item.qty_ordered)'),
+        ];
+
+        $select->from(
+            ['source_table' => $this->getTable('sales_order')],
+            $columns
+        )->joinInner(
+            ['order_item' => $this->getTable('sales_order_item')],
+            'order_item.order_id = source_table.entity_id',
+            []
+        )->joinLeft(
+            ['order_item_parent' => $this->getTable('sales_order_item')],
+            'order_item.parent_item_id = order_item_parent.item_id',
+            []
+        )->where(
+            "source_table.entity_id IN (SELECT entity_id FROM " . $this->getTable('sales_order') .
+            " WHERE store_id = " . $storeId .
+            " AND state != '" . \Magento\Sales\Model\Order::STATE_CANCELED . "'" .
+            ($subSelect !== null ?
+                " AND " . $this->_makeConditionFromDateRangeSelect($subSelect, $periodExpr) :
+                '') . ")"
+        )->where(
+            'order_item.product_type NOT IN(?)',
+            $this->ignoredProductTypes
+        );
+
+        $select->useStraightJoin();
+        // important!
+        $insertQuery = $select->insertFromSelect($this->getMainTable(), array_keys($columns));
+        $connection->query($insertQuery);
+    }
+
     /**
      * Update rating position
      *
      * @param string $aggregation
      * @return $this
+     * @throws LocalizedException
      */
     protected function _updateRatingPos($aggregation)
     {
diff --git a/vendor/magento/module-sales/etc/db_schema.xml b/vendor/magento/module-sales/etc/db_schema.xml
index 491772e7e65..2f1cf0904ac 100644
--- a/vendor/magento/module-sales/etc/db_schema.xml
+++ b/vendor/magento/module-sales/etc/db_schema.xml
@@ -294,6 +294,11 @@
         <index referenceId="SALES_ORDER_EMAIL_SENT" indexType="btree">
             <column name="email_sent"/>
         </index>
+        <index referenceId="SALES_ORDER_STORE_STATE_CREATED" indexType="btree">
+            <column name="store_id"/>
+            <column name="state"/>
+            <column name="created_at"/>
+        </index>
     </table>
     <table name="sales_order_grid" resource="sales" engine="innodb" comment="Sales Flat Order Grid">
         <column xsi:type="int" name="entity_id" unsigned="true" nullable="false" identity="false"
diff --git a/vendor/magento/module-sales/etc/db_schema_whitelist.json b/vendor/magento/module-sales/etc/db_schema_whitelist.json
index 02efd7d5a00..664c65d36c3 100644
--- a/vendor/magento/module-sales/etc/db_schema_whitelist.json
+++ b/vendor/magento/module-sales/etc/db_schema_whitelist.json
@@ -142,6 +142,7 @@
             "SALES_ORDER_STATUS": true,
             "SALES_ORDER_STATE": true,
             "SALES_ORDER_STORE_ID": true,
+            "SALES_ORDER_STORE_ID_STATE_CREATED_AT": true,
             "SALES_ORDER_CREATED_AT": true,
             "SALES_ORDER_CUSTOMER_ID": true,
             "SALES_ORDER_EXT_ORDER_ID": true,
