Commit 66e4e1db0e for woocommerce

commit 66e4e1db0e5222881db108d889ff77db84573abd
Author: Vladimir Reznichenko <kalessil@gmail.com>
Date:   Tue Jan 20 08:32:58 2026 +0100

    [Performance] Admin: reduce the number of SQL queries needed for fetching settings (#62853)

    In this PR, we leverage `wp_prime_option_caches` to bulk-prefetch entries from the options table used further in the settings context. When the cache is primed, `get_option` uses the in-memory cache rather than issuing SQL queries for each entry.

diff --git a/plugins/woocommerce/changelog/performance-admin-reduce-sqls-number-settings b/plugins/woocommerce/changelog/performance-admin-reduce-sqls-number-settings
new file mode 100644
index 0000000000..f082a0a1af
--- /dev/null
+++ b/plugins/woocommerce/changelog/performance-admin-reduce-sqls-number-settings
@@ -0,0 +1,4 @@
+Significance: patch
+Type: performance
+
+The number of SQL queries required to fetch settings on admin pages has been reduced to improve performance.
diff --git a/plugins/woocommerce/includes/class-wc-emails.php b/plugins/woocommerce/includes/class-wc-emails.php
index 4f137a43c3..959fd22936 100644
--- a/plugins/woocommerce/includes/class-wc-emails.php
+++ b/plugins/woocommerce/includes/class-wc-emails.php
@@ -272,29 +272,40 @@ class WC_Emails {
 		// Include email classes.
 		include_once __DIR__ . '/emails/class-wc-email.php';

-		$this->emails['WC_Email_New_Order']                 = include __DIR__ . '/emails/class-wc-email-new-order.php';
-		$this->emails['WC_Email_Cancelled_Order']           = include __DIR__ . '/emails/class-wc-email-cancelled-order.php';
-		$this->emails['WC_Email_Customer_Cancelled_Order']  = include __DIR__ . '/emails/class-wc-email-customer-cancelled-order.php';
-		$this->emails['WC_Email_Failed_Order']              = include __DIR__ . '/emails/class-wc-email-failed-order.php';
-		$this->emails['WC_Email_Customer_Failed_Order']     = include __DIR__ . '/emails/class-wc-email-customer-failed-order.php';
-		$this->emails['WC_Email_Customer_On_Hold_Order']    = include __DIR__ . '/emails/class-wc-email-customer-on-hold-order.php';
-		$this->emails['WC_Email_Customer_Processing_Order'] = include __DIR__ . '/emails/class-wc-email-customer-processing-order.php';
-		$this->emails['WC_Email_Customer_Completed_Order']  = include __DIR__ . '/emails/class-wc-email-customer-completed-order.php';
-		$this->emails['WC_Email_Customer_Refunded_Order']   = include __DIR__ . '/emails/class-wc-email-customer-refunded-order.php';
-		$this->emails['WC_Email_Customer_Invoice']          = include __DIR__ . '/emails/class-wc-email-customer-invoice.php';
-		$this->emails['WC_Email_Customer_Note']             = include __DIR__ . '/emails/class-wc-email-customer-note.php';
-		$this->emails['WC_Email_Customer_Reset_Password']   = include __DIR__ . '/emails/class-wc-email-customer-reset-password.php';
-		$this->emails['WC_Email_Customer_New_Account']      = include __DIR__ . '/emails/class-wc-email-customer-new-account.php';
-
+		$emails = array(
+			'WC_Email_New_Order'                 => __DIR__ . '/emails/class-wc-email-new-order.php',
+			'WC_Email_Cancelled_Order'           => __DIR__ . '/emails/class-wc-email-cancelled-order.php',
+			'WC_Email_Customer_Cancelled_Order'  => __DIR__ . '/emails/class-wc-email-customer-cancelled-order.php',
+			'WC_Email_Failed_Order'              => __DIR__ . '/emails/class-wc-email-failed-order.php',
+			'WC_Email_Customer_Failed_Order'     => __DIR__ . '/emails/class-wc-email-customer-failed-order.php',
+			'WC_Email_Customer_On_Hold_Order'    => __DIR__ . '/emails/class-wc-email-customer-on-hold-order.php',
+			'WC_Email_Customer_Processing_Order' => __DIR__ . '/emails/class-wc-email-customer-processing-order.php',
+			'WC_Email_Customer_Completed_Order'  => __DIR__ . '/emails/class-wc-email-customer-completed-order.php',
+			'WC_Email_Customer_Refunded_Order'   => __DIR__ . '/emails/class-wc-email-customer-refunded-order.php',
+			'WC_Email_Customer_Invoice'          => __DIR__ . '/emails/class-wc-email-customer-invoice.php',
+			'WC_Email_Customer_Note'             => __DIR__ . '/emails/class-wc-email-customer-note.php',
+			'WC_Email_Customer_Reset_Password'   => __DIR__ . '/emails/class-wc-email-customer-reset-password.php',
+			'WC_Email_Customer_New_Account'      => __DIR__ . '/emails/class-wc-email-customer-new-account.php',
+		);
 		if ( FeaturesUtil::feature_is_enabled( 'point_of_sale' ) ) {
-			$this->emails['WC_Email_Customer_POS_Completed_Order'] = include __DIR__ . '/emails/class-wc-email-customer-pos-completed-order.php';
-			$this->emails['WC_Email_Customer_POS_Refunded_Order']  = include __DIR__ . '/emails/class-wc-email-customer-pos-refunded-order.php';
+			$emails['WC_Email_Customer_POS_Completed_Order'] = __DIR__ . '/emails/class-wc-email-customer-pos-completed-order.php';
+			$emails['WC_Email_Customer_POS_Refunded_Order']  = __DIR__ . '/emails/class-wc-email-customer-pos-refunded-order.php';
 		}
-
 		if ( FeaturesUtil::feature_is_enabled( 'fulfillments' ) ) {
-			$this->emails['WC_Email_Customer_Fulfillment_Created'] = include __DIR__ . '/emails/class-wc-email-customer-fulfillment-created.php';
-			$this->emails['WC_Email_Customer_Fulfillment_Updated'] = include __DIR__ . '/emails/class-wc-email-customer-fulfillment-updated.php';
-			$this->emails['WC_Email_Customer_Fulfillment_Deleted'] = include __DIR__ . '/emails/class-wc-email-customer-fulfillment-deleted.php';
+			$emails['WC_Email_Customer_Fulfillment_Created'] = __DIR__ . '/emails/class-wc-email-customer-fulfillment-created.php';
+			$emails['WC_Email_Customer_Fulfillment_Updated'] = __DIR__ . '/emails/class-wc-email-customer-fulfillment-updated.php';
+			$emails['WC_Email_Customer_Fulfillment_Deleted'] = __DIR__ . '/emails/class-wc-email-customer-fulfillment-deleted.php';
+		}
+
+		// Preload the options which will be used when emails are getting initialized in the loop below (reduces the number of SQL-queries).
+		wp_prime_option_caches(
+			array_map(
+				fn( string $class_name ) => sprintf( 'woocommerce_%s_settings', strtolower( str_replace( 'WC_Email_', '', $class_name ) ) ),
+				array_keys( $emails )
+			)
+		);
+		foreach ( $emails as $class => $path ) {
+			$this->emails[ $class ] = include $path;
 		}

 		/**
diff --git a/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-customers-v1-controller.php b/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-customers-v1-controller.php
index abad2afe45..5bc451ef2c 100644
--- a/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-customers-v1-controller.php
+++ b/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-customers-v1-controller.php
@@ -42,6 +42,14 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller {
 	 * Register the routes for customers.
 	 */
 	public function register_routes() {
+		// Preload the options which will be used in this method (reduces the number of SQL-queries).
+		wp_prime_option_caches(
+			array(
+				'woocommerce_registration_generate_username',
+				'woocommerce_registration_generate_password',
+			)
+		);
+
 		register_rest_route( $this->namespace, '/' . $this->rest_base, array(
 			array(
 				'methods'             => WP_REST_Server::READABLE,
diff --git a/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php b/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php
index 0884dfe592..a3cdc6f421 100644
--- a/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php
+++ b/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php
@@ -172,6 +172,8 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller {
 			return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) );
 		}

+		$this->prime_options_cache_for_settings( $settings );
+
 		$filtered_settings = array();
 		foreach ( $settings as $setting ) {
 			$option_key = $setting['option_key'];
@@ -206,6 +208,30 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller {
 		return $filtered_settings;
 	}

+	/**
+	 * Primes options cache to reduce the number of SQLs towards options table.
+	 *
+	 * @param mixed[] $settings The settings to prefetch options for.
+	 * @return void
+	 */
+	protected function prime_options_cache_for_settings( array $settings ): void {
+		$prefetch = array();
+		foreach ( $settings as $setting ) {
+			$option_key = $setting['option_key'];
+			if ( is_array( $option_key ) ) {
+				$prefetch[] = $option_key[0];
+			} elseif ( strstr( $option_key, '[' ) ) {
+				parse_str( $option_key, $option_array );
+				$prefetch[] = current( array_keys( $option_array ) );
+			} else {
+				$prefetch[] = $option_key;
+			}
+		}
+		if ( array() !== $prefetch ) {
+			wp_prime_option_caches( $prefetch );
+		}
+	}
+
 	/**
 	 * Returns a list of countries and states for use in the base location setting.
 	 *
diff --git a/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-setting-options-controller.php b/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-setting-options-controller.php
index 8cd1e56ff5..5d9336a254 100644
--- a/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-setting-options-controller.php
+++ b/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-setting-options-controller.php
@@ -82,6 +82,8 @@ class WC_REST_Setting_Options_Controller extends WC_REST_Setting_Options_V2_Cont
 			return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) );
 		}

+		$this->prime_options_cache_for_settings( $settings );
+
 		$filtered_settings = array();
 		foreach ( $settings as $setting ) {
 			$option_key = $setting['option_key'];
diff --git a/plugins/woocommerce/src/Internal/Admin/Settings.php b/plugins/woocommerce/src/Internal/Admin/Settings.php
index 51a7fc648f..26ffa1e42b 100644
--- a/plugins/woocommerce/src/Internal/Admin/Settings.php
+++ b/plugins/woocommerce/src/Internal/Admin/Settings.php
@@ -154,6 +154,7 @@ class Settings {
 		//phpcs:ignore
 		$preload_options = apply_filters( 'woocommerce_admin_preload_options', array() );
 		if ( ! empty( $preload_options ) ) {
+			wp_prime_option_caches( $preload_options );
 			foreach ( $preload_options as $option ) {
 				$settings['preloadOptions'][ $option ] = get_option( $option );
 			}