diff --git a/vendor/magento/module-target-rule/Model/Rule.php b/vendor/magento/module-target-rule/Model/Rule.php
index 9476094361f..c9b70424ab5 100644
--- a/vendor/magento/module-target-rule/Model/Rule.php
+++ b/vendor/magento/module-target-rule/Model/Rule.php
@@ -7,6 +7,8 @@
 namespace Magento\TargetRule\Model;
 
 use Magento\Framework\Exception\LocalizedException;
+use Magento\Catalog\Model\Product;
+use Magento\Catalog\Model\ResourceModel\Product\Collection as ProductCollection;
 
 /**
  * TargetRule Rule Model
@@ -177,6 +179,27 @@ class Rule extends \Magento\Rule\Model\AbstractModel
         );
     }
 
+    /**
+     * Get products from provided collection
+     *
+     * @param ProductCollection $collection
+     * @return \Generator|Product[]
+     */
+    private function getProducts(ProductCollection $collection): \Generator
+    {
+        $collection->setPageSize(1000);
+        $pageCount = $collection->getLastPageNumber();
+        $currentPage = 1;
+        while ($currentPage <= $pageCount) {
+            $collection->setCurPage($currentPage);
+            foreach ($collection as $key => $product) {
+                yield $key => $product;
+            }
+            $collection->clear();
+            $currentPage++;
+        }
+    }
+
     /**
      * Set resource model
      *
@@ -211,7 +234,7 @@ class Rule extends \Magento\Rule\Model\AbstractModel
      */
     public function afterSave()
     {
-        if ($this->isObjectNew() || $this->dataHasChangedForAny([
+        $data = [
             'is_active',
             'from_date',
             'to_date',
@@ -219,7 +242,8 @@ class Rule extends \Magento\Rule\Model\AbstractModel
             'apply_to',
             'actions',
             'customer_segment_ids',
-        ])) {
+        ];
+        if ($this->isObjectNew() || $this->dataHasChangedForAny($data)) {
             $this->_ruleProductIndexerProcessor->reindexRow($this->getId());
         }
         return parent::afterSave();
@@ -308,9 +332,9 @@ class Rule extends \Magento\Rule\Model\AbstractModel
         }
 
         $this->_productIds = [];
-        foreach (array_unique($productCollection->getAllIds()) as $productId) {
-            if ($this->getConditions()->validateByEntityId($productId)) {
-                $this->_productIds[] = $productId;
+        foreach ($this->getProducts($productCollection) as $product) {
+            if ($this->getConditions()->validate($product)) {
+                $this->_productIds[] = $product->getId();
             }
         }
         return $this;
diff --git a/vendor/magento/module-target-rule/Model/Rule/Condition/Product/Attributes/SqlBuilder.php b/vendor/magento/module-target-rule/Model/Rule/Condition/Product/Attributes/SqlBuilder.php
index 816c3b0d66c..19f6c946b24 100644
--- a/vendor/magento/module-target-rule/Model/Rule/Condition/Product/Attributes/SqlBuilder.php
+++ b/vendor/magento/module-target-rule/Model/Rule/Condition/Product/Attributes/SqlBuilder.php
@@ -306,7 +306,9 @@ class SqlBuilder
             \Magento\Framework\DB\Select::SQL_UNION
         );
 
-        return 'e.' . $linkField . ' IN (' . $resultSelect . ')';
+        /** MySQL Subquery with IN statement performance optimizer */
+        $selectWrapper = $this->indexResource->getConnection()->select()->from($resultSelect);
+        return 'e.' . $linkField . ' IN (' . $selectWrapper . ')';
     }
 
     /**
