From 127209a9feee6290b421cc4d3dd0b40e8f8ed72b Mon Sep 17 00:00:00 2001 From: spacedmonkey Date: Fri, 15 Sep 2023 16:15:22 +0000 Subject: [PATCH] Options, Meta APIs: Optimize get_option by relocating notoptions cache lookup. In the get_option function, a cache lookup for the notoptions key is performed, which stores an array of keys for options known not to exist. This optimization prevents repeated database queries when certain options are requested. However, the cache lookup for notoptions was conducted before checking if the requested option exists in the cache. Given that it's more likely that the option does exist, this commit reorders the checks to first verify the option's existence in the cache before confirming its absence. This adjustment reduces redundant queries and also eliminates an unnecessary cache lookup, improving overall performance. Props spacedmonkey, costdev, flixos90, azaozz. Fixes #58277. Built from https://develop.svn.wordpress.org/trunk@56595 git-svn-id: http://core.svn.wordpress.org/trunk@56107 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-includes/option.php | 56 ++++++++++++++++++----------------------- wp-includes/version.php | 2 +- 2 files changed, 26 insertions(+), 32 deletions(-) diff --git a/wp-includes/option.php b/wp-includes/option.php index fc2f8ddce1cd..c207c5ca1d1e 100644 --- a/wp-includes/option.php +++ b/wp-includes/option.php @@ -161,33 +161,6 @@ function get_option( $option, $default_value = false ) { $passed_default = func_num_args() > 1; if ( ! wp_installing() ) { - // Prevent non-existent options from triggering multiple queries. - $notoptions = wp_cache_get( 'notoptions', 'options' ); - - // Prevent non-existent `notoptions` key from triggering multiple key lookups. - if ( ! is_array( $notoptions ) ) { - $notoptions = array(); - wp_cache_set( 'notoptions', $notoptions, 'options' ); - } - - if ( isset( $notoptions[ $option ] ) ) { - /** - * Filters the default value for an option. - * - * The dynamic portion of the hook name, `$option`, refers to the option name. - * - * @since 3.4.0 - * @since 4.4.0 The `$option` parameter was added. - * @since 4.7.0 The `$passed_default` parameter was added to distinguish between a `false` value and the default parameter value. - * - * @param mixed $default_value The default value to return if the option does not exist - * in the database. - * @param string $option Option name. - * @param bool $passed_default Was `get_option()` passed a default value? - */ - return apply_filters( "default_option_{$option}", $default_value, $option, $passed_default ); - } - $alloptions = wp_load_alloptions(); if ( isset( $alloptions[ $option ] ) ) { @@ -196,6 +169,31 @@ function get_option( $option, $default_value = false ) { $value = wp_cache_get( $option, 'options' ); if ( false === $value ) { + // Prevent non-existent options from triggering multiple queries. + $notoptions = wp_cache_get( 'notoptions', 'options' ); + + // Prevent non-existent `notoptions` key from triggering multiple key lookups. + if ( ! is_array( $notoptions ) ) { + $notoptions = array(); + wp_cache_set( 'notoptions', $notoptions, 'options' ); + } elseif ( isset( $notoptions[ $option ] ) ) { + /** + * Filters the default value for an option. + * + * The dynamic portion of the hook name, `$option`, refers to the option name. + * + * @since 3.4.0 + * @since 4.4.0 The `$option` parameter was added. + * @since 4.7.0 The `$passed_default` parameter was added to distinguish between a `false` value and the default parameter value. + * + * @param mixed $default_value The default value to return if the option does not exist + * in the database. + * @param string $option Option name. + * @param bool $passed_default Was `get_option()` passed a default value? + */ + return apply_filters( "default_option_{$option}", $default_value, $option, $passed_default ); + } + $row = $wpdb->get_row( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", $option ) ); // Has to be get_row() instead of get_var() because of funkiness with 0, false, null values. @@ -203,10 +201,6 @@ function get_option( $option, $default_value = false ) { $value = $row->option_value; wp_cache_add( $option, $value, 'options' ); } else { // Option does not exist, so we must cache its non-existence. - if ( ! is_array( $notoptions ) ) { - $notoptions = array(); - } - $notoptions[ $option ] = true; wp_cache_set( 'notoptions', $notoptions, 'options' ); diff --git a/wp-includes/version.php b/wp-includes/version.php index c1ddfc537654..6d835817cbbf 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -16,7 +16,7 @@ * * @global string $wp_version */ -$wp_version = '6.4-alpha-56594'; +$wp_version = '6.4-alpha-56595'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.