diff --git a/vendor/magento/module-sales/Model/ResourceModel/Report/Bestsellers.php b/vendor/magento/module-sales/Model/ResourceModel/Report/Bestsellers.php
index e37e8ab843e73..13a8f8d9589f3 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,41 @@ 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;
+
+    /**
+     * @var array
+     */
+    private array $rangesByQuery = [];
+
+    /**
+     * @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 +99,7 @@ public function __construct(
         $this->_productResource = $productResource;
         $this->_salesResourceHelper = $salesResourceHelper;
         $this->ignoredProductTypes = array_merge($this->ignoredProductTypes, $ignoredProductTypes);
+        $this->storeManager = $storeManager ?: ObjectManager::getInstance()->get(StoreManagerInterface::class);
     }
 
     /**
@@ -92,116 +119,217 @@ protected function _construct()
      * @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->clearByDateRange($from, $to);
+        foreach ($this->storeManager->getStores(true) as $store) {
+            $this->processStoreAggregate($store->getId(), $from, $to);
+        }
+
+        $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)'),
+        ];
+
+        $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->clearTableRanges($this->getMainTable(), $from, $to, $subSelect);
+    }
+
+    /**
+     * Clear table by date range
+     *
+     * @param string $table
+     * @param ?string $from
+     * @param ?string $to
+     * @param null|Select|string $subSelect
+     * @return void
+     */
+    private function clearTableRanges($table, $from = null, $to = null, $subSelect = null): void
+    {
+        if ($from === null && $to === null) {
+            $this->_truncateTable($table);
+            return;
+        }
+
+        if ($subSelect !== null) {
+            $dataRange = $this->getRange($subSelect);
+            $deleteCondition = $this->getConnection()->prepareSqlCondition('period', ['in' => $dataRange]);
+            $this->getConnection()->delete($table, $deleteCondition);
+            return;
+        } else {
+            $condition = [];
+            if ($from !== null) {
+                $condition[] = $this->getConnection()->quoteInto('period >= ?', $from);
             }
 
-            $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
-            );
+            if ($to !== null) {
+                $condition[] = $this->getConnection()->quoteInto('period <= ?', $to);
+            }
+            $deleteCondition = implode(' AND ', $condition);
+        }
+        $this->getConnection()->delete($table, $deleteCondition);
+    }
+
+    /**
+     * Get dates range to clear the table
+     *
+     * @param Select $select
+     * @return array
+     */
+    private function getRange(Select $select): array
+    {
+        $queryHash = sha1($select->__toString());
+        if (!isset($this->rangesByQuery[$queryHash])) {
 
-            if ($subSelect !== null) {
-                $select->having($this->_makeConditionFromDateRangeSelect($subSelect, 'period'));
+            $connection = $this->getConnection();
+            try {
+                $query = $connection->query($select);
+                $range = $query->fetchAll(\Zend_Db::FETCH_COLUMN);
+            } catch (\Exception) {
+                $range = [];
             }
 
-            $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
+            $this->rangesByQuery[$queryHash] = $range;
+        }
+        return $this->rangesByQuery[$queryHash];
+    }
+
+    /**
+     * 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
+    {
+        $subSelect = null;
+        if ($from !== null || $to !== null) {
+            $subSelect = $this->_getTableDateRangeSelect(
+                $this->getTable('sales_order'),
+                'created_at',
+                'updated_at',
+                $from,
+                $to
             );
+        }
 
-            if ($subSelect !== null) {
-                $select->where($this->_makeConditionFromDateRangeSelect($subSelect, 'period'));
-            }
+        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();
 
-            $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;
+        // convert dates to current admin timezone
+        $periodExpr = $connection->getDatePartSql(
+            $this->getStoreTZOffsetQuery(
+                ['source_table' => $this->getTable('sales_order')],
+                'source_table.created_at',
+                $from,
+                $to
+            )
+        );
+
+        $subSelect = $this->getRangeSubSelect($from, $to);
+        if ($subSelect) {
+            $dataRange = $this->getRange($subSelect);
+            $whereCondition = $connection->prepareSqlCondition($periodExpr, ['in' => $dataRange]);
         }
 
-        return $this;
+        $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.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 " . $whereCondition :
+                '') . ")"
+        )->where(
+            'order_item.product_type NOT IN(?)',
+            $this->ignoredProductTypes
+        );
+
+        $select->useStraightJoin();
+        // important!
+        $insertQuery = $select->insertFromSelect($this->getMainTable(), array_keys($columns));
+        $connection->query($insertQuery);
     }
 
     /**
@@ -209,6 +337,7 @@ public function aggregate($from = null, $to = null)
      *
      * @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 112e927bf4c9d..3297d96c6ef7d 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 02efd7d5a0050..664c65d36c3c7 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,
