Make WordPress Core


Ignore:
Timestamp:
09/29/2015 09:59:44 PM (11 years ago)
Author:
boonebgorges
Message:

Improve lazyloading of term metadata in WP_Query loops.

[34529] introduced lazyloading for the metadata belonging to terms matching
posts in the main WP_Query. The current changeset improves this technique
in the following ways:

  • Term meta lazyloading is now performed on the results of all WP_Query queries, not just the main query.
  • Fewer global variable touches and greater encapsulation.
  • The logic for looping through posts to identify terms is now only performed once per WP_Query.

Props dlh, boonebgorges.
See #34047.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/term/meta.php

    r34538 r34704  
    146146        }
    147147
     148        /**
     149         * @ticket 34073
     150         */
     151        public function test_term_meta_should_be_lazy_loaded_only_for_the_queries_in_which_the_term_has_posts() {
     152                global $wpdb;
     153
     154                $posts = $this->factory->post->create_many( 3, array( 'post_status' => 'publish' ) );
     155                register_taxonomy( 'wptests_tax', 'post' );
     156                $terms = $this->factory->term->create_many( 6, array( 'taxonomy' => 'wptests_tax' ) );
     157
     158                wp_set_object_terms( $posts[0], array( $terms[0], $terms[1] ), 'wptests_tax' );
     159                wp_set_object_terms( $posts[1], array( $terms[2], $terms[3] ), 'wptests_tax' );
     160                wp_set_object_terms( $posts[2], array( $terms[0], $terms[4], $terms[5] ), 'wptests_tax' );
     161
     162                foreach ( $terms as $t ) {
     163                        add_term_meta( $t, 'foo', 'bar' );
     164                }
     165
     166                $q0 = new WP_Query( array( 'p' => $posts[0] ) );
     167                $q1 = new WP_Query( array( 'p' => $posts[1] ) );
     168                $q2 = new WP_Query( array( 'p' => $posts[2] ) );
     169
     170                /*
     171                 * $terms[0] belongs to both $posts[0] and $posts[2], so `get_term_meta( $terms[0] )` should prime
     172                 * the cache for term matched by $q0 and $q2.
     173                 */
     174
     175                // First request will hit the database.
     176                $num_queries = $wpdb->num_queries;
     177
     178                // Prime caches.
     179                $this->assertSame( 'bar', get_term_meta( $terms[0], 'foo', true ) );
     180
     181                // Two queries: one for $q0 and one for $q2.
     182                $num_queries += 2;
     183                $this->assertSame( $num_queries, $wpdb->num_queries );
     184
     185                // Next requests should be in cache.
     186                $this->assertSame( 'bar', get_term_meta( $terms[1], 'foo', true ) );
     187                $this->assertSame( 'bar', get_term_meta( $terms[4], 'foo', true ) );
     188                $this->assertSame( 'bar', get_term_meta( $terms[5], 'foo', true ) );
     189                $this->assertSame( $num_queries, $wpdb->num_queries );
     190
     191                // Querying for $terms[2] will prime $terms[3] as well.
     192                $this->assertSame( 'bar', get_term_meta( $terms[2], 'foo', true ) );
     193                $num_queries++;
     194                $this->assertSame( $num_queries, $wpdb->num_queries );
     195
     196                $this->assertSame( 'bar', get_term_meta( $terms[3], 'foo', true ) );
     197                $this->assertSame( $num_queries, $wpdb->num_queries );
     198        }
     199
    148200        public function test_adding_term_meta_should_bust_get_terms_cache() {
    149201                $terms = $this->factory->term->create_many( 2, array( 'taxonomy' => 'wptests_tax' ) );
Note: See TracChangeset for help on using the changeset viewer.