[wp-trac] [WordPress Trac] #59188: WP_Posts_List_Table causes post, page, and term caches to be primed for all pages in the DB on load
WordPress Trac
noreply at wordpress.org
Thu Aug 24 16:38:02 UTC 2023
#59188: WP_Posts_List_Table causes post, page, and term caches to be primed for all
pages in the DB on load
-----------------------------------------+-----------------------------
Reporter: kevinfodness | Owner: (none)
Type: defect (bug) | Status: new
Priority: normal | Milestone: Awaiting Review
Component: Query | Version:
Severity: normal | Keywords:
Focuses: administration, performance |
-----------------------------------------+-----------------------------
This behavior primarily triggers if a user is using an external object
cache on the second load of /wp-admin/edit.php?post_type=page once the
query cache has been populated for id=>parent relationships for pages. It
is reproducible on the Pages listing, but will also apply to any custom
post type declared as hierarchical.
The WP_Posts_List_Table class has a method called prepare_items which is
called when building the table view at /wp-admin/edit.php?post_type=page.
This function calls wp_edit_posts_query():
https://github.com/WordPress/WordPress/blob/master/wp-admin/includes
/class-wp-posts-list-table.php#L165
This function checks to see if the post type is hierarchical, and if it
is, sets posts_per_page to -1. This is done because it wouldn't be
possible to build a hierarchical view of posts with pagination without
understanding the relationship between all of the IDs in the database for
that post type:
https://github.com/WordPress/WordPress/blob/master/wp-
admin/includes/post.php#L1274
Once the query parameters are built, they are passed to the wp function
for execution:
https://github.com/WordPress/WordPress/blob/master/wp-
admin/includes/post.php#L1283
The wp function then calls the main method on the global $wp object, which
runs query_posts, which calls $wp_the_query->query, which invokes
get_posts on a WP_Query object.
Once the query is built, WP_Query attempts to see if there are cached
results for that query:
https://github.com/WordPress/WordPress/blob/master/wp-includes/class-wp-
query.php#L3173
If cached results are found (which would only happen after the query was
run once and cached, hence my comment above about why this only triggers
on the second load of the pages view with a persistent object cache in
play like memcached) then this logic block flows down to where it forks
based on what was requested in 'fields', which in this case is not just
IDs, it's id=>parent relationships, so it flows into the else and triggers
_prime_post_caches for all pages (or any other hierarchical post type)
including all post meta and all terms attached to those posts. Although
the prime post caches function will only prime caches for posts that
aren't already in the cache, if the cache was recently flushed or cache
salts or versions rotated, this can be a very expensive operation that can
crash a site if it's loading in a significant number of hierarchical posts
and/or if those posts have a lot of metadata.
I would recommend marking a query that is looking for id=>parent with a
posts_per_page of -1 as not cacheable to prevent this behavior.
Note: I created this ticket during WordCamp US Contributor Day, and was
having trouble with Core Trac being overloaded with requests, which
inhibited my ability to search for related tickets. If this is a
duplicate, I apologize, and will be happy to contribute to related
tickets.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/59188>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list