Commit c2f08ec1ca for woocommerce
commit c2f08ec1ca7bf7f2b63e846db06995bb9b294e0c
Author: Vladimir Reznichenko <kalessil@gmail.com>
Date: Tue Jan 20 08:13:42 2026 +0100
[Performance] Slow comments queries in admin: add new index and use caches priming for reviews page (#62805)
The new index enhances performance for counting and grouping comments queries in the admin area.
We also updated the posts priming style and added priming to the reviews page to reduce SQL queries.
diff --git a/plugins/woocommerce/changelog/performance-62767-slow-comments-queries-in-admin b/plugins/woocommerce/changelog/performance-62767-slow-comments-queries-in-admin
new file mode 100644
index 0000000000..c12a73f360
--- /dev/null
+++ b/plugins/woocommerce/changelog/performance-62767-slow-comments-queries-in-admin
@@ -0,0 +1,4 @@
+Significance: patch
+Type: performance
+
+Admin: Improved the performance of approved comment counting and reduced the number of SQL queries on the product reviews page.
diff --git a/plugins/woocommerce/includes/admin/class-wc-admin-dashboard.php b/plugins/woocommerce/includes/admin/class-wc-admin-dashboard.php
index f54f6a9862..dea1f19b1b 100644
--- a/plugins/woocommerce/includes/admin/class-wc-admin-dashboard.php
+++ b/plugins/woocommerce/includes/admin/class-wc-admin-dashboard.php
@@ -497,16 +497,12 @@ if ( ! class_exists( 'WC_Admin_Dashboard', false ) ) :
/** @var \WP_Comment[] $comments */ // phpcs:ignore Generic.Commenting.DocComment.MissingShort
$comments = get_comments(
array(
- 'type' => 'review',
- 'status' => 'approve',
- 'number' => 5,
+ 'type' => 'review',
+ 'status' => 'approve',
+ 'number' => 5,
+ 'update_comment_post_cache' => true,
)
);
- _prime_post_caches(
- array_map( static fn( \WP_Comment $comment ) => (int) $comment->comment_post_ID, $comments ),
- false,
- false
- );
$comments = array_filter(
$comments,
static fn( \WP_Comment $comment ) => current_user_can( 'read_product', $comment->comment_post_ID )
diff --git a/plugins/woocommerce/includes/class-wc-install.php b/plugins/woocommerce/includes/class-wc-install.php
index 79908674dd..21dfd0df08 100644
--- a/plugins/woocommerce/includes/class-wc-install.php
+++ b/plugins/woocommerce/includes/class-wc-install.php
@@ -319,6 +319,9 @@ class WC_Install {
'wc_update_1050_add_idx_user_email',
'wc_update_1050_remove_deprecated_marketplace_option',
),
+ '10.6.0' => array(
+ 'wc_update_1060_add_woo_idx_comment_approved_type_index',
+ ),
);
/**
@@ -1720,21 +1723,25 @@ class WC_Install {
$db_delta_result = dbDelta( self::get_schema() );
- $comment_type_index_exists = $wpdb->get_row( "SHOW INDEX FROM {$wpdb->comments} WHERE column_name = 'comment_type' and key_name = 'woo_idx_comment_type'" );
-
- if ( is_null( $comment_type_index_exists ) ) {
+ $comment_type_index_exists = $wpdb->get_row( "SHOW INDEX FROM {$wpdb->comments} WHERE key_name = 'woo_idx_comment_type'" );
+ if ( null === $comment_type_index_exists ) {
// Add an index to the field comment_type to improve the response time of the query
// used by WC_Comments::wp_count_comments() to get the number of comments by type.
$wpdb->query( "ALTER TABLE {$wpdb->comments} ADD INDEX woo_idx_comment_type (comment_type)" );
}
$date_type_index_exists = $wpdb->get_row( "SHOW INDEX FROM {$wpdb->comments} WHERE key_name = 'woo_idx_comment_date_type'" );
-
- if ( is_null( $date_type_index_exists ) ) {
+ if ( null === $date_type_index_exists ) {
// Improve performance of the admin comments query when fetching the latest 25 comments while excluding reviews and internal notes.
$wpdb->query( "ALTER TABLE {$wpdb->comments} ADD INDEX woo_idx_comment_date_type (comment_date_gmt, comment_type, comment_approved, comment_post_ID)" );
}
+ $comment_approved_type_index_exists = $wpdb->get_row( "SHOW INDEX FROM {$wpdb->comments} WHERE key_name = 'woo_idx_comment_approved_type'" );
+ if ( null === $comment_approved_type_index_exists ) {
+ // Improve performance of the admin comments query when counting approved comments while excluding internal notes.
+ $wpdb->query( "ALTER TABLE {$wpdb->comments} ADD INDEX woo_idx_comment_approved_type (comment_approved, comment_type, comment_post_ID)" );
+ }
+
// Clear table caches.
delete_transient( 'wc_attribute_taxonomies' );
diff --git a/plugins/woocommerce/includes/wc-update-functions.php b/plugins/woocommerce/includes/wc-update-functions.php
index 0878f2e08a..88b3a29714 100644
--- a/plugins/woocommerce/includes/wc-update-functions.php
+++ b/plugins/woocommerce/includes/wc-update-functions.php
@@ -3230,3 +3230,20 @@ function wc_update_1050_enable_autoload_options() {
function wc_update_1050_remove_deprecated_marketplace_option(): void {
delete_option( 'woocommerce_feature_marketplace_enabled' );
}
+
+/**
+ * Add the `woo_idx_comment_approved_type` index to improve the performance of comment-related queries in the admin area.
+ *
+ * @since 10.6.0
+ *
+ * @return void
+ */
+function wc_update_1060_add_woo_idx_comment_approved_type_index(): void {
+ global $wpdb;
+
+ $comment_approved_type_index_exists = $wpdb->get_row( "SHOW INDEX FROM {$wpdb->comments} WHERE key_name = 'woo_idx_comment_approved_type'" );
+ if ( null === $comment_approved_type_index_exists ) {
+ // Improve performance of the admin comments query when counting approved comments while excluding internal notes.
+ $wpdb->query( "ALTER TABLE {$wpdb->comments} ADD INDEX woo_idx_comment_approved_type (comment_approved, comment_type, comment_post_ID)" );
+ }
+}
diff --git a/plugins/woocommerce/phpstan-baseline.neon b/plugins/woocommerce/phpstan-baseline.neon
index 96ca7c53ea..49a270e2f0 100644
--- a/plugins/woocommerce/phpstan-baseline.neon
+++ b/plugins/woocommerce/phpstan-baseline.neon
@@ -67143,12 +67143,6 @@ parameters:
count: 1
path: src/Internal/Admin/ProductReviews/ReviewsListTable.php
- -
- message: '#^Parameter \#1 \$comments of function update_comment_cache expects array\<WP_Comment\>, array\<int\|WP_Comment\>\|int given\.$#'
- identifier: argument.type
- count: 1
- path: src/Internal/Admin/ProductReviews/ReviewsListTable.php
-
-
message: '#^Parameter \#1 \$number of function number_format_i18n expects float, int\|string given\.$#'
identifier: argument.type
@@ -67185,12 +67179,6 @@ parameters:
count: 2
path: src/Internal/Admin/ProductReviews/ReviewsListTable.php
- -
- message: '#^Property WP_List_Table\:\:\$items \(array\) does not accept array\<int\|WP_Comment\>\|int\.$#'
- identifier: assign.propertyType
- count: 1
- path: src/Internal/Admin/ProductReviews/ReviewsListTable.php
-
-
message: '#^Parameter \#1 \$post of function get_post_type expects int\|WP_Post\|null, string given\.$#'
identifier: argument.type
diff --git a/plugins/woocommerce/src/Internal/Admin/ProductReviews/ReviewsListTable.php b/plugins/woocommerce/src/Internal/Admin/ProductReviews/ReviewsListTable.php
index d1ef887549..3e9f7b7497 100644
--- a/plugins/woocommerce/src/Internal/Admin/ProductReviews/ReviewsListTable.php
+++ b/plugins/woocommerce/src/Internal/Admin/ProductReviews/ReviewsListTable.php
@@ -76,8 +76,9 @@ class ReviewsListTable extends WP_List_Table {
$this->set_review_product();
$args = [
- 'number' => $this->get_per_page(),
- 'post_type' => 'product',
+ 'number' => $this->get_per_page(),
+ 'post_type' => 'product',
+ 'update_comment_post_cache' => true,
];
// Include the order & orderby arguments.
@@ -103,11 +104,10 @@ class ReviewsListTable extends WP_List_Table {
*
* @param array $args Comment query args.
*/
- $args = (array) apply_filters( 'woocommerce_product_reviews_list_table_prepare_items_args', $args );
- $comments = get_comments( $args );
-
- update_comment_cache( $comments );
+ $args = (array) apply_filters( 'woocommerce_product_reviews_list_table_prepare_items_args', $args );
+ /** @var \WP_Comment[] $comments */ // phpcs:ignore Generic.Commenting.DocComment.MissingShort
+ $comments = get_comments( $args );
$this->items = $comments;
$this->set_pagination_args(
diff --git a/plugins/woocommerce/uninstall.php b/plugins/woocommerce/uninstall.php
index aeb30e4d8b..df6dfb9e5f 100644
--- a/plugins/woocommerce/uninstall.php
+++ b/plugins/woocommerce/uninstall.php
@@ -59,6 +59,10 @@ if ( defined( 'WC_REMOVE_ALL_DATA' ) && true === WC_REMOVE_ALL_DATA ) {
if ( null !== $date_type_index_exists ) {
$wpdb->query( "ALTER TABLE {$wpdb->comments} DROP INDEX woo_idx_comment_date_type;" );
}
+ $comment_approved_type_index_exists = $wpdb->get_row( "SHOW INDEX FROM {$wpdb->comments} WHERE key_name = 'woo_idx_comment_approved_type';" );
+ if ( null !== $comment_approved_type_index_exists ) {
+ $wpdb->query( "ALTER TABLE {$wpdb->comments} DROP INDEX woo_idx_comment_approved_type;" );
+ }
// Roles + caps.
WC_Install::remove_roles();