diff -Nuar a/vendor/magento/module-catalog-rule/Cron/DailyCatalogUpdate.php b/vendor/magento/module-catalog-rule/Cron/DailyCatalogUpdate.php
index 7f584fb1154..116a4529a8e 100644
--- a/vendor/magento/module-catalog-rule/Cron/DailyCatalogUpdate.php
+++ b/vendor/magento/module-catalog-rule/Cron/DailyCatalogUpdate.php
@@ -6,19 +6,34 @@
 
 namespace Magento\CatalogRule\Cron;
 
+use Magento\CatalogRule\Model\Indexer\PartialIndex;
+use Magento\CatalogRule\Model\Indexer\Rule\RuleProductProcessor;
+
+/**
+ * Daily update catalog price rule by cron
+ */
 class DailyCatalogUpdate
 {
     /**
-     * @var \Magento\CatalogRule\Model\Indexer\Rule\RuleProductProcessor
+     * @var RuleProductProcessor
      */
     protected $ruleProductProcessor;
 
     /**
-     * @param \Magento\CatalogRule\Model\Indexer\Rule\RuleProductProcessor $ruleProductProcessor
+     * @var PartialIndex
      */
-    public function __construct(\Magento\CatalogRule\Model\Indexer\Rule\RuleProductProcessor $ruleProductProcessor)
-    {
+    private $partialIndex;
+
+    /**
+     * @param RuleProductProcessor $ruleProductProcessor
+     * @param PartialIndex $partialIndex
+     */
+    public function __construct(
+        RuleProductProcessor $ruleProductProcessor,
+        PartialIndex $partialIndex
+    ) {
         $this->ruleProductProcessor = $ruleProductProcessor;
+        $this->partialIndex = $partialIndex;
     }
 
     /**
@@ -31,6 +46,8 @@ class DailyCatalogUpdate
      */
     public function execute()
     {
-        $this->ruleProductProcessor->markIndexerAsInvalid();
+        $this->ruleProductProcessor->isIndexerScheduled()
+            ? $this->partialIndex->partialUpdateCatalogRuleProductPrice()
+            : $this->ruleProductProcessor->markIndexerAsInvalid();
     }
 }
diff -Nuar a/vendor/magento/module-catalog-rule/Model/Indexer/PartialIndex.php b/vendor/magento/module-catalog-rule/Model/Indexer/PartialIndex.php
new file mode 100644
index 00000000000..12a77f81826
--- /dev/null
+++ b/vendor/magento/module-catalog-rule/Model/Indexer/PartialIndex.php
@@ -0,0 +1,97 @@
+<?php
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+declare(strict_types=1);
+
+namespace Magento\CatalogRule\Model\Indexer;
+
+use Magento\Framework\DB\Adapter\AdapterInterface;
+use Magento\Framework\App\ResourceConnection;
+
+/**
+ * Catalog rule partial index
+ *
+ * This class triggers the dependent index "catalog_product_price",
+ * and the cache is cleared only for the matched products for partial indexing.
+ */
+class PartialIndex
+{
+    /**
+     * @var ResourceConnection
+     */
+    private $resource;
+
+    /**
+     * @var AdapterInterface
+     */
+    private $connection;
+
+    /**
+     * @var IndexBuilder
+     */
+    private $indexBuilder;
+
+    /**
+     * @param ResourceConnection $resource
+     * @param IndexBuilder $indexBuilder
+     */
+    public function __construct(
+        ResourceConnection $resource,
+        IndexBuilder $indexBuilder
+    ) {
+        $this->resource = $resource;
+        $this->connection = $resource->getConnection();
+        $this->indexBuilder = $indexBuilder;
+    }
+
+    /**
+     * Synchronization replica table with original table "catalogrule_product_price"
+     *
+     * Used replica table for correctly working MySQL trigger
+     *
+     * @return void
+     */
+    public function partialUpdateCatalogRuleProductPrice(): void
+    {
+        $this->indexBuilder->reindexFull();
+        $indexTableName = $this->resource->getTableName('catalogrule_product_price');
+        $select = $this->connection->select()->from(
+            ['crp' => $indexTableName],
+            'product_id'
+        );
+        $selectFields = $this->connection->select()->from(
+            ['crp' => $indexTableName],
+            [
+                'rule_date',
+                'customer_group_id',
+                'product_id',
+                'rule_price',
+                'website_id',
+                'latest_start_date',
+                'earliest_end_date',
+            ]
+        );
+        $where = ['product_id' .' NOT IN (?)' => $select];
+        //remove products that are no longer used in indexing
+        $this->connection->delete($this->resource->getTableName('catalogrule_product_price_replica'), $where);
+        //add updated products to indexing
+        $this->connection->query(
+            $this->connection->insertFromSelect(
+                $selectFields,
+                $this->resource->getTableName('catalogrule_product_price_replica'),
+                [
+                    'rule_date',
+                    'customer_group_id',
+                    'product_id',
+                    'rule_price',
+                    'website_id',
+                    'latest_start_date',
+                    'earliest_end_date',
+                ],
+                AdapterInterface::INSERT_ON_DUPLICATE
+            )
+        );
+    }
+}
diff -Nuar a/vendor/magento/module-catalog-rule/etc/mview.xml b/vendor/magento/module-catalog-rule/etc/mview.xml
index 35efe33461a..984215d66db 100644
--- a/vendor/magento/module-catalog-rule/etc/mview.xml
+++ b/vendor/magento/module-catalog-rule/etc/mview.xml
@@ -27,6 +27,7 @@
     <view id="catalog_product_price" class="Magento\Catalog\Model\Indexer\Product\Price" group="indexer">
         <subscriptions>
             <table name="catalogrule_product_price" entity_column="product_id" />
+            <table name="catalogrule_product_price_replica" entity_column="product_id" />
         </subscriptions>
     </view>
 </config>
