Commit f9ac88b3df3 for woocommerce

commit f9ac88b3df33703a47c52ce2a4472c661435eb67
Author: Benito Alba Molina <albamolina.benito@gmail.com>
Date:   Thu Aug 13 02:31:49 2026 +0200

    Skip review lookup updates when reviews are disabled (#66524)

    * Skip review lookup updates when reviews are disabled

    * Add changelog entry for disabled review lookup updates

    ---------

    Co-authored-by: benitoalba <benitoalba@users.noreply.github.com>

diff --git a/plugins/woocommerce/changelog/41225-performance-skip-review-lookup-updates b/plugins/woocommerce/changelog/41225-performance-skip-review-lookup-updates
new file mode 100644
index 00000000000..bd3ed33cf58
--- /dev/null
+++ b/plugins/woocommerce/changelog/41225-performance-skip-review-lookup-updates
@@ -0,0 +1,4 @@
+Significance: patch
+Type: performance
+
+Improve performance when product reviews are disabled by skipping product rating lookup table updates.
diff --git a/plugins/woocommerce/includes/wc-product-functions.php b/plugins/woocommerce/includes/wc-product-functions.php
index 362a94b4d5b..026aca1e8cd 100644
--- a/plugins/woocommerce/includes/wc-product-functions.php
+++ b/plugins/woocommerce/includes/wc-product-functions.php
@@ -1959,7 +1959,8 @@ function wc_update_product_lookup_tables_is_running() {
 function wc_update_product_lookup_tables() {
 	global $wpdb;

-	$is_cli = Constants::is_true( 'WP_CLI' );
+	$is_cli          = Constants::is_true( 'WP_CLI' );
+	$reviews_enabled = wc_reviews_enabled();

 	// Note that the table is not yet generated.
 	update_option( 'woocommerce_product_lookup_table_is_generating', true );
@@ -1993,6 +1994,10 @@ function wc_update_product_lookup_tables() {
 	);

 	foreach ( $columns as $index => $column ) {
+		if ( 'average_rating' === $column && ! $reviews_enabled ) {
+			continue;
+		}
+
 		if ( $is_cli ) {
 			wc_update_product_lookup_tables_column( $column );
 		} else {
@@ -2007,6 +2012,10 @@ function wc_update_product_lookup_tables() {
 		}
 	}

+	if ( ! $reviews_enabled ) {
+		return;
+	}
+
 	// Rating counts are serialised so they have to be unserialised before populating the lookup table.
 	if ( $is_cli ) {
 		$rating_count_rows = $wpdb->get_results(
@@ -2042,6 +2051,11 @@ function wc_update_product_lookup_tables_column( $column ) {
 	if ( empty( $column ) ) {
 		return;
 	}
+
+	if ( 'average_rating' === $column && ! wc_reviews_enabled() ) {
+		return;
+	}
+
 	global $wpdb;
 	switch ( $column ) {
 		case 'min_max_price':
@@ -2200,7 +2214,7 @@ function wc_update_product_lookup_tables_rating_count( $rows ) {
 function wc_update_product_lookup_tables_rating_count_batch( $offset = 0, $limit = 0 ) {
 	global $wpdb;

-	if ( ! $limit ) {
+	if ( ! $limit || ! wc_reviews_enabled() ) {
 		return;
 	}

diff --git a/plugins/woocommerce/tests/php/includes/wc-product-functions-test.php b/plugins/woocommerce/tests/php/includes/wc-product-functions-test.php
index ec214e71f34..89e943c51f6 100644
--- a/plugins/woocommerce/tests/php/includes/wc-product-functions-test.php
+++ b/plugins/woocommerce/tests/php/includes/wc-product-functions-test.php
@@ -15,6 +15,19 @@ use Automattic\WooCommerce\Testing\Tools\CodeHacking\Hacks\StaticMockerHack;
  * Class WC_Stock_Functions_Tests.
  */
 class WC_Product_Functions_Tests extends \WC_Unit_Test_Case {
+	/**
+	 * The original product reviews setting.
+	 *
+	 * @var mixed
+	 */
+	private $original_reviews_setting;
+
+	/**
+	 * Whether the current test changed the product reviews setting.
+	 *
+	 * @var bool
+	 */
+	private $reviews_setting_changed = false;

 	/**
 	 * Reset the variation gallery feature-flag option after each test so
@@ -22,6 +35,18 @@ class WC_Product_Functions_Tests extends \WC_Unit_Test_Case {
 	 */
 	public function tearDown(): void {
 		delete_option( \Automattic\WooCommerce\Internal\VariationGallery\Package::ENABLE_OPTION_NAME );
+
+		if ( $this->reviews_setting_changed ) {
+			delete_option( 'woocommerce_product_lookup_table_is_generating' );
+			as_unschedule_all_actions( '', array(), 'wc_update_product_lookup_tables' );
+
+			if ( null === $this->original_reviews_setting ) {
+				delete_option( 'woocommerce_enable_reviews' );
+			} else {
+				update_option( 'woocommerce_enable_reviews', $this->original_reviews_setting );
+			}
+		}
+
 		parent::tearDown();
 	}

@@ -572,6 +597,130 @@ class WC_Product_Functions_Tests extends \WC_Unit_Test_Case {
 		$this->assertEquals( 100, (float) $lookup_after->min_price, 'Lookup table min_price should reflect regular price' );
 	}

+	/**
+	 * @testdox Product lookup table regeneration schedules review data updates only when reviews are enabled.
+	 * @testWith ["yes", true]
+	 *           ["no", false]
+	 *
+	 * @param string $reviews_setting       The product reviews setting.
+	 * @param bool   $expect_review_updates Whether review data updates should be scheduled.
+	 */
+	public function test_wc_update_product_lookup_tables_schedules_review_data_only_when_reviews_are_enabled( string $reviews_setting, bool $expect_review_updates ): void {
+		$this->set_reviews_setting_for_lookup_table_test( $reviews_setting );
+
+		wc_update_product_lookup_tables();
+
+		$average_rating_scheduled = as_has_scheduled_action(
+			'wc_update_product_lookup_tables_column',
+			array( 'column' => 'average_rating' ),
+			'wc_update_product_lookup_tables'
+		);
+		$rating_count_scheduled   = as_has_scheduled_action(
+			'wc_update_product_lookup_tables_rating_count_batch',
+			array(
+				'offset' => 0,
+				'limit'  => 50,
+			),
+			'wc_update_product_lookup_tables'
+		);
+
+		$this->assertSame( $expect_review_updates, (bool) $average_rating_scheduled, 'Average rating regeneration should follow the product reviews setting.' );
+		$this->assertSame( $expect_review_updates, (bool) $rating_count_scheduled, 'Rating count regeneration should follow the product reviews setting.' );
+		$this->assertTrue(
+			(bool) as_has_scheduled_action(
+				'wc_update_product_lookup_tables_column',
+				array( 'column' => 'min_max_price' ),
+				'wc_update_product_lookup_tables'
+			),
+			'Unrelated lookup table columns should still be scheduled.'
+		);
+	}
+
+	/**
+	 * @testdox Queued average rating updates do not run when reviews are disabled.
+	 * @testWith ["yes", 4.5]
+	 *           ["no", 1.0]
+	 *
+	 * @param string $reviews_setting The product reviews setting.
+	 * @param float  $expected_rating The expected lookup table rating.
+	 */
+	public function test_wc_update_product_lookup_tables_column_respects_reviews_setting( string $reviews_setting, float $expected_rating ): void {
+		global $wpdb;
+
+		$product = WC_Helper_Product::create_simple_product();
+		update_post_meta( $product->get_id(), '_wc_average_rating', '4.50' );
+		$wpdb->update(
+			$wpdb->wc_product_meta_lookup,
+			array( 'average_rating' => 1.0 ),
+			array( 'product_id' => $product->get_id() )
+		);
+		$this->set_reviews_setting_for_lookup_table_test( $reviews_setting );
+
+		wc_update_product_lookup_tables_column( 'average_rating' );
+
+		$actual_rating = (float) $wpdb->get_var(
+			$wpdb->prepare(
+				"SELECT average_rating FROM {$wpdb->wc_product_meta_lookup} WHERE product_id = %d",
+				$product->get_id()
+			)
+		);
+		$this->assertSame( $expected_rating, $actual_rating, 'Average rating lookup data should only update when reviews are enabled.' );
+	}
+
+	/**
+	 * @testdox Queued rating count batches do not run when reviews are disabled.
+	 * @testWith ["yes", 3, true]
+	 *           ["no", 1, false]
+	 *
+	 * @param string $reviews_setting  The product reviews setting.
+	 * @param int    $expected_count   The expected lookup table rating count.
+	 * @param bool   $expect_follow_up Whether another batch should be scheduled.
+	 */
+	public function test_wc_update_product_lookup_tables_rating_count_batch_respects_reviews_setting( string $reviews_setting, int $expected_count, bool $expect_follow_up ): void {
+		global $wpdb;
+
+		$product = WC_Helper_Product::create_simple_product();
+		update_post_meta( $product->get_id(), '_wc_rating_count', array( 5 => 3 ) );
+		$wpdb->update(
+			$wpdb->wc_product_meta_lookup,
+			array( 'rating_count' => 1 ),
+			array( 'product_id' => $product->get_id() )
+		);
+		$this->set_reviews_setting_for_lookup_table_test( $reviews_setting );
+
+		wc_update_product_lookup_tables_rating_count_batch( 0, 50 );
+
+		$actual_count        = (int) $wpdb->get_var(
+			$wpdb->prepare(
+				"SELECT rating_count FROM {$wpdb->wc_product_meta_lookup} WHERE product_id = %d",
+				$product->get_id()
+			)
+		);
+		$follow_up_scheduled = as_has_scheduled_action(
+			'wc_update_product_lookup_tables_rating_count_batch',
+			array(
+				'offset' => 50,
+				'limit'  => 50,
+			),
+			'wc_update_product_lookup_tables'
+		);
+
+		$this->assertSame( $expected_count, $actual_count, 'Rating count lookup data should only update when reviews are enabled.' );
+		$this->assertSame( $expect_follow_up, (bool) $follow_up_scheduled, 'Follow-up rating count batches should only be scheduled when reviews are enabled.' );
+	}
+
+	/**
+	 * Set the product reviews option and reset lookup table actions for a test.
+	 *
+	 * @param string $reviews_setting The product reviews setting.
+	 */
+	private function set_reviews_setting_for_lookup_table_test( string $reviews_setting ): void {
+		$this->original_reviews_setting = get_option( 'woocommerce_enable_reviews', null );
+		$this->reviews_setting_changed  = true;
+		as_unschedule_all_actions( '', array(), 'wc_update_product_lookup_tables' );
+		update_option( 'woocommerce_enable_reviews', $reviews_setting );
+	}
+
 	/**
 	 * @testDox Action Scheduler events are scheduled when product with sale dates is saved.
 	 */