Taxonomy: Improve performance by taxonomy queries by adding a limitting requested terms.

Add a limit to the number of terms requested in taxonomy queries. This improves the performance of the query and the likelihood of hitting an existing term query cache. 

Props Spacedmonkey, peterwilsoncc, flixos90. 
Fixes #55360. 



git-svn-id: https://develop.svn.wordpress.org/trunk@53037 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Jonny Harris
2022-03-31 10:04:25 +00:00
parent 1d0c189f21
commit ed3854948f
2 changed files with 124 additions and 0 deletions

View File

@@ -637,6 +637,10 @@ class WP_Tax_Query {
break;
}
if ( ! is_taxonomy_hierarchical( $query['taxonomy'] ) ) {
$args['number'] = count( $terms );
}
$term_query = new WP_Term_Query();
$term_list = $term_query->query( $args );

View File

@@ -1621,4 +1621,124 @@ class Tests_Query_TaxQuery extends WP_UnitTestCase {
$this->assertSameSets( array( $p ), $q->posts );
}
/**
* @ticket 55360
*
* @covers WP_Tax_Query::transform_query
*/
public function test_tax_terms_should_limit_query() {
$filter = new MockAction();
add_filter( 'terms_pre_query', array( $filter, 'filter' ), 10, 2 );
register_taxonomy( 'wptests_tax', 'post' );
$name = 'foobar';
$t = self::factory()->term->create(
array(
'taxonomy' => 'wptests_tax',
'name' => $name,
)
);
$p = self::factory()->post->create();
wp_set_object_terms( $p, array( $t ), 'wptests_tax' );
$q = new WP_Query(
array(
'fields' => 'ids',
'tax_query' => array(
array(
'taxonomy' => 'wptests_tax',
'field' => 'name',
'terms' => $name,
),
),
)
);
$filter_args = $filter->get_args();
$query = $filter_args[1][1]->request;
$this->assertSameSets( array( $p ), $q->posts );
$this->assertStringContainsString( 'LIMIT 1', $query );
}
/**
* @ticket 55360
*
* @covers WP_Tax_Query::transform_query
*/
public function test_tax_terms_should_limit_query_to_one() {
$filter = new MockAction();
add_filter( 'terms_pre_query', array( $filter, 'filter' ), 10, 2 );
register_taxonomy( 'wptests_tax', 'post' );
$name = 'foobar';
$t = self::factory()->term->create(
array(
'taxonomy' => 'wptests_tax',
'name' => $name,
)
);
$p = self::factory()->post->create();
wp_set_object_terms( $p, array( $t ), 'wptests_tax' );
$q = new WP_Query(
array(
'fields' => 'ids',
'tax_query' => array(
array(
'taxonomy' => 'wptests_tax',
'field' => 'term_id',
'terms' => array( $t, $t, $t ),
),
),
)
);
$filter_args = $filter->get_args();
$query = $filter_args[1][1]->request;
$this->assertSameSets( array( $p ), $q->posts );
$this->assertStringContainsString( 'LIMIT 1', $query );
}
/**
* @ticket 55360
*
* @covers WP_Tax_Query::transform_query
*/
public function test_hierarchical_taxonomies_do_not_limit_query() {
$filter = new MockAction();
add_filter( 'terms_pre_query', array( $filter, 'filter' ), 10, 2 );
register_taxonomy( 'wptests_tax', 'post', array( 'hierarchical' => true ) );
$name = 'foobar';
$t = self::factory()->term->create(
array(
'taxonomy' => 'wptests_tax',
'name' => $name,
)
);
$p = self::factory()->post->create();
wp_set_object_terms( $p, array( $t ), 'wptests_tax' );
$q = new WP_Query(
array(
'fields' => 'ids',
'tax_query' => array(
array(
'taxonomy' => 'wptests_tax',
'field' => 'name',
'terms' => $name,
),
),
)
);
$filter_args = $filter->get_args();
$query = $filter_args[0][1]->request;
$this->assertSameSets( array( $p ), $q->posts );
$this->assertStringNotContainsString( 'LIMIT 1', $query );
}
}