Commit e1e4a4b6ce8 for woocommerce
commit e1e4a4b6ce814dfab3cde22ca54d945320ec8b97
Author: Vladimir Reznichenko <kalessil@gmail.com>
Date: Mon Oct 26 21:02:14 2026 +0100
[Performance] Fix N+1 query pattern in StoreAPI (ProductSchema::get_item_response) (#70228)
diff --git a/plugins/woocommerce/changelog/performance-product-page-prime-hierarchical-terms b/plugins/woocommerce/changelog/performance-product-page-prime-hierarchical-terms
new file mode 100644
index 00000000000..be93e8a9638
--- /dev/null
+++ b/plugins/woocommerce/changelog/performance-product-page-prime-hierarchical-terms
@@ -0,0 +1,4 @@
+Significance: patch
+Type: performance
+
+Fixed N+1 query pattern in StoreAPI (ProductSchema::get_item_response method).
diff --git a/plugins/woocommerce/src/StoreApi/Schemas/V1/ProductSchema.php b/plugins/woocommerce/src/StoreApi/Schemas/V1/ProductSchema.php
index 486e2a7628f..a8ad46c38eb 100644
--- a/plugins/woocommerce/src/StoreApi/Schemas/V1/ProductSchema.php
+++ b/plugins/woocommerce/src/StoreApi/Schemas/V1/ProductSchema.php
@@ -611,6 +611,7 @@ class ProductSchema extends AbstractSchema {
}
)
);
+ $this->prime_product_hierarchical_taxonomies_cache( $product );
return [
'id' => $product->get_id(),
@@ -684,6 +685,42 @@ class ProductSchema extends AbstractSchema {
return $parent_id && '' !== get_post_field( 'post_password', $parent_id, 'raw' );
}
+ /**
+ * Prime hierarchical terms cache to reduce queries while generating terms lists in get_item_response method.
+ *
+ * @param \WC_Product $product Product instance.
+ * @return void
+ */
+ private function prime_product_hierarchical_taxonomies_cache( \WC_Product $product ): void {
+ $term_hierarchy_ids = array();
+ foreach ( array( 'product_cat', 'product_brand' ) as $taxonomy ) {
+ $product_terms = get_object_term_cache( $product->get_id(), $taxonomy );
+ $product_terms = is_array( $product_terms ) ? $product_terms : array();
+ $taxonomy_hierarchy = ! empty( $product_terms ) ? _get_term_hierarchy( $taxonomy ) : array();
+ if ( ! empty( $taxonomy_hierarchy ) ) {
+ // Populate flat map of child to parent relations.
+ $parent_map = array();
+ foreach ( $taxonomy_hierarchy as $parent_id => $children ) {
+ foreach ( $children as $child_id ) {
+ $parent_map[ $child_id ] = $parent_id;
+ }
+ }
+ // Collect the chain of parent term IDs for cache priming below.
+ foreach ( $product_terms as $term ) {
+ $current = $term->term_id;
+ while ( isset( $parent_map[ $current ] ) ) {
+ $parent_id = $parent_map[ $current ];
+ $term_hierarchy_ids[] = $parent_id;
+ $current = $parent_id;
+ }
+ }
+ }
+ }
+ if ( ! empty( $term_hierarchy_ids ) ) {
+ _prime_term_caches( array_unique( $term_hierarchy_ids ), false );
+ }
+ }
+
/**
* Get list of product images.
*