diff --git a/vendor/magento/module-catalog-inventory/Model/ResourceModel/Indexer/Stock/DefaultStock.php b/vendor/magento/module-catalog-inventory/Model/ResourceModel/Indexer/Stock/DefaultStock.php
index bfb84a9ffa9..da22f0bee50 100644
--- a/vendor/magento/module-catalog-inventory/Model/ResourceModel/Indexer/Stock/DefaultStock.php
+++ b/vendor/magento/module-catalog-inventory/Model/ResourceModel/Indexer/Stock/DefaultStock.php
@@ -8,6 +8,7 @@ namespace Magento\CatalogInventory\Model\ResourceModel\Indexer\Stock;
 
 use Magento\Catalog\Model\ResourceModel\Product\Indexer\AbstractIndexer;
 use Magento\CatalogInventory\Model\Stock;
+use Magento\Framework\App\ObjectManager;
 use Magento\Framework\DB\Adapter\AdapterInterface;
 use Magento\CatalogInventory\Api\StockConfigurationInterface;
 use Magento\CatalogInventory\Model\Indexer\Stock\Action\Full;
@@ -26,22 +27,16 @@ use Magento\Catalog\Model\Product\Attribute\Source\Status as ProductStatus;
 class DefaultStock extends AbstractIndexer implements StockInterface
 {
     /**
-     * Current Product Type Id
-     *
      * @var string
      */
     protected $_typeId;
 
     /**
-     * Product Type is composite flag
-     *
      * @var bool
      */
     protected $_isComposite = false;
 
     /**
-     * Core store config
-     *
      * @var \Magento\Framework\App\Config\ScopeConfigInterface
      */
     protected $_scopeConfig;
@@ -58,12 +53,15 @@ class DefaultStock extends AbstractIndexer implements StockInterface
     protected $stockConfiguration;
 
     /**
-     * Param for switching logic which depends on action type (full reindex or partial)
-     *
      * @var string
      */
     private $actionType;
 
+    /**
+     * @var GetStatusExpression
+     */
+    private $getStatusExpression;
+
     /**
      * Class constructor
      *
@@ -72,16 +70,21 @@ class DefaultStock extends AbstractIndexer implements StockInterface
      * @param \Magento\Eav\Model\Config $eavConfig
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param string $connectionName
+     * @param \Magento\CatalogInventory\Model\ResourceModel\Indexer\Stock\GetStatusExpression|null $getStatusExpression
      */
     public function __construct(
         \Magento\Framework\Model\ResourceModel\Db\Context $context,
         \Magento\Framework\Indexer\Table\StrategyInterface $tableStrategy,
         \Magento\Eav\Model\Config $eavConfig,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        $connectionName = null
+        $connectionName = null,
+        \Magento\CatalogInventory\Model\ResourceModel\Indexer\Stock\GetStatusExpression $getStatusExpression = null
     ) {
         $this->_scopeConfig = $scopeConfig;
         parent::__construct($context, $tableStrategy, $eavConfig, $connectionName);
+        $this->getStatusExpression = $getStatusExpression ?: ObjectManager::getInstance()->get(
+            \Magento\CatalogInventory\Model\ResourceModel\Indexer\Stock\GetStatusExpression::class
+        );
     }
 
     /**
@@ -251,6 +254,10 @@ class DefaultStock extends AbstractIndexer implements StockInterface
             . ' AND mcpei.attribute_id = ' . $this->_getAttribute('status')->getId()
             . ' AND mcpei.value = ' . ProductStatus::STATUS_ENABLED,
             []
+        )->joinLeft(
+            ['css' => $this->getTable('cataloginventory_stock_status')],
+            'css.product_id = e.entity_id',
+            []
         )->columns(
             ['qty' => $qtyExpr]
         )->where(
@@ -292,7 +299,6 @@ class DefaultStock extends AbstractIndexer implements StockInterface
      */
     protected function _updateIndex($entityIds)
     {
-        $this->deleteOldRecords($entityIds);
         $connection = $this->getConnection();
         $select = $this->_getStockStatusSelect($entityIds, true);
         $select = $this->getQueryProcessorComposite()->processQuery($select, $entityIds, true);
@@ -300,6 +306,7 @@ class DefaultStock extends AbstractIndexer implements StockInterface
 
         $i = 0;
         $data = [];
+        $savedEntityIds = [];
         while ($row = $query->fetch(\PDO::FETCH_ASSOC)) {
             $i++;
             $data[] = [
@@ -309,6 +316,7 @@ class DefaultStock extends AbstractIndexer implements StockInterface
                 'qty' => (double)$row['qty'],
                 'stock_status' => (int)$row['status'],
             ];
+            $savedEntityIds[] = (int)$row['entity_id'];
             if ($i % 1000 == 0) {
                 $this->_updateIndexTable($data);
                 $data = [];
@@ -317,6 +325,7 @@ class DefaultStock extends AbstractIndexer implements StockInterface
 
         $this->_updateIndexTable($data);
 
+        $this->deleteOldRecords(array_diff($entityIds, $savedEntityIds));
         return $this;
     }
 
@@ -376,21 +385,7 @@ class DefaultStock extends AbstractIndexer implements StockInterface
      */
     protected function getStatusExpression(AdapterInterface $connection, $isAggregate = false)
     {
-        $isInStockExpression = $isAggregate ? 'MAX(cisi.is_in_stock)' : 'cisi.is_in_stock';
-        if ($this->_isManageStock()) {
-            $statusExpr = $connection->getCheckSql(
-                'cisi.use_config_manage_stock = 0 AND cisi.manage_stock = 0',
-                1,
-                $isInStockExpression
-            );
-        } else {
-            $statusExpr = $connection->getCheckSql(
-                'cisi.use_config_manage_stock = 0 AND cisi.manage_stock = 1',
-                $isInStockExpression,
-                1
-            );
-        }
-        return $statusExpr;
+        return $this->getStatusExpression->execute($this->getTypeId(), $connection, $isAggregate);
     }
 
     /**
diff --git a/vendor/magento/module-catalog-inventory/Model/ResourceModel/Indexer/Stock/GetStatusExpression.php b/vendor/magento/module-catalog-inventory/Model/ResourceModel/Indexer/Stock/GetStatusExpression.php
new file mode 100644
index 00000000000..0b7ee4f578a
--- /dev/null
+++ b/vendor/magento/module-catalog-inventory/Model/ResourceModel/Indexer/Stock/GetStatusExpression.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+declare(strict_types=1);
+
+namespace Magento\CatalogInventory\Model\ResourceModel\Indexer\Stock;
+
+use InvalidArgumentException;
+use Magento\CatalogInventory\Model\ResourceModel\Indexer\Stock\StatusExpression\ExpressionInterface;
+use Magento\Framework\DB\Adapter\AdapterInterface;
+use Zend_Db_Expr;
+
+class GetStatusExpression
+{
+    /**
+     * @var array
+     */
+    private $statusExpressions;
+
+    /**
+     * @param array $statusExpressions
+     */
+    public function __construct(array $statusExpressions = [])
+    {
+        foreach ($statusExpressions as $expression) {
+            if (!($expression instanceof ExpressionInterface)) {
+                throw new InvalidArgumentException(
+                    'Expressions must implement '
+                    .'\Magento\CatalogInventory\Model\ResourceModel\Indexer\Stock\StatusExpression\ExpressionInterface'
+                    .' interface'
+                );
+            }
+        }
+        $this->statusExpressions = $statusExpressions;
+    }
+
+    /**
+     * Returns stock status expression for MySQL query.
+     *
+     * @param string $productType
+     * @param AdapterInterface $connection
+     * @param bool $isAggregate
+     * @return Zend_Db_Expr|null
+     */
+    public function execute(string $productType, AdapterInterface $connection, bool $isAggregate): ?Zend_Db_Expr
+    {
+        $expression = $this->statusExpressions[$productType] ?? $this->statusExpressions['default'];
+        return $expression->getExpression($connection, $isAggregate);
+    }
+}
diff --git a/vendor/magento/module-catalog-inventory/Model/ResourceModel/Indexer/Stock/StatusExpression/DefaultExpression.php b/vendor/magento/module-catalog-inventory/Model/ResourceModel/Indexer/Stock/StatusExpression/DefaultExpression.php
new file mode 100644
index 00000000000..a7e97f7b6d6
--- /dev/null
+++ b/vendor/magento/module-catalog-inventory/Model/ResourceModel/Indexer/Stock/StatusExpression/DefaultExpression.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CatalogInventory\Model\ResourceModel\Indexer\Stock\StatusExpression;
+
+use Magento\CatalogInventory\Model\Configuration;
+use Magento\Framework\App\Config\ScopeConfigInterface;
+use Magento\Framework\DB\Adapter\AdapterInterface;
+use Magento\Store\Model\ScopeInterface;
+use Zend_Db_Expr;
+
+class DefaultExpression implements ExpressionInterface
+{
+    /**
+     * @var ScopeConfigInterface
+     */
+    private $scopeConfig;
+
+    /**
+     * @param ScopeConfigInterface $scopeConfig
+     */
+    public function __construct(ScopeConfigInterface $scopeConfig)
+    {
+        $this->scopeConfig = $scopeConfig;
+    }
+
+    /**
+     * Returns status expressions for MySQL query
+     *
+     * @ingeritdoc
+     * @param AdapterInterface $connection
+     * @param bool $isAggregate
+     * @return Zend_Db_Expr
+     */
+    public function getExpression(AdapterInterface $connection, bool $isAggregate): Zend_Db_Expr
+    {
+        $isManageStock = $this->scopeConfig->isSetFlag(
+            Configuration::XML_PATH_MANAGE_STOCK,
+            ScopeInterface::SCOPE_STORE
+        );
+
+        $isInStockExpression = $isAggregate ? 'MAX(cisi.is_in_stock)' : 'cisi.is_in_stock';
+        if ($isManageStock) {
+            $statusExpr = $connection->getCheckSql(
+                'cisi.use_config_manage_stock = 0 AND cisi.manage_stock = 0',
+                1,
+                $isInStockExpression
+            );
+        } else {
+            $statusExpr = $connection->getCheckSql(
+                'cisi.use_config_manage_stock = 0 AND cisi.manage_stock = 1',
+                $isInStockExpression,
+                1
+            );
+        }
+        return $statusExpr;
+    }
+}
diff --git a/vendor/magento/module-catalog-inventory/Model/ResourceModel/Indexer/Stock/StatusExpression/ExpressionInterface.php b/vendor/magento/module-catalog-inventory/Model/ResourceModel/Indexer/Stock/StatusExpression/ExpressionInterface.php
new file mode 100644
index 00000000000..1e2738ff983
--- /dev/null
+++ b/vendor/magento/module-catalog-inventory/Model/ResourceModel/Indexer/Stock/StatusExpression/ExpressionInterface.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CatalogInventory\Model\ResourceModel\Indexer\Stock\StatusExpression;
+
+use Magento\Framework\DB\Adapter\AdapterInterface;
+use Zend_Db_Expr;
+
+/**
+ * Interface for composite status expressions for MySQL query.
+ */
+interface ExpressionInterface
+{
+    /**
+     * Returns status expressions for MySQL query
+     *
+     * @param AdapterInterface $connection
+     * @param bool $isAggregate
+     * @return Zend_Db_Expr
+     */
+    public function getExpression(AdapterInterface $connection, bool $isAggregate): Zend_Db_Expr;
+}
diff --git a/vendor/magento/module-catalog-inventory/etc/di.xml b/vendor/magento/module-catalog-inventory/etc/di.xml
index d2807249cf5..4de38b29402 100644
--- a/vendor/magento/module-catalog-inventory/etc/di.xml
+++ b/vendor/magento/module-catalog-inventory/etc/di.xml
@@ -133,4 +133,11 @@
     <type name="Magento\Catalog\Controller\Adminhtml\Product\Action\Attribute\Save">
         <plugin name="massAction" type="Magento\CatalogInventory\Plugin\MassUpdateProductAttribute" />
     </type>
+    <type name="Magento\CatalogInventory\Model\ResourceModel\Indexer\Stock\GetStatusExpression">
+        <arguments>
+            <argument name="statusExpressions" xsi:type="array">
+                <item name="default" xsi:type="object">Magento\CatalogInventory\Model\ResourceModel\Indexer\Stock\StatusExpression\DefaultExpression</item>
+            </argument>
+        </arguments>
+    </type>
 </config>

