Opened 6 years ago
Closed 6 years ago
#45105 closed defect (bug) (fixed)
wp_list_authors() performance issue. Queries for user data on authors with no posts
Reported by: | billerickson | Owned by: | ianbelanger |
---|---|---|---|
Milestone: | 5.2 | Priority: | normal |
Severity: | normal | Version: | |
Component: | Users | Keywords: | has-patch commit |
Focuses: | performance | Cc: |
Description
On a client site with a single author, 4 posts, and thousands of subscribers (a membership site), we were getting over 17,000 queries on a 404 page that included the wp_list_authors() function: https://cl.ly/aa7ed29b1815
To reproduce this issue:
- Install Query Monitor + Debug Bar
- Add wp_list_authors() to a page and note the number of queries
- Generate new users (wp user generate) and notice the increase in queries
The key issue is the check for empty posts runs after get_userdata() is called, so a query for that user's metadata happens regardless of their post count.
Moving the post count check above get_userdata() fixes the issue.
Attachments (2)
Change History (12)
#1
@
6 years ago
- Component changed from General to Users
- Milestone changed from Awaiting Review to 5.1
- Owner set to SergeyBiryukov
- Status changed from new to reviewing
#3
@
6 years ago
This issue affects almost every Genesis-based website. The default Genesis 404 page builds a sitemap listing all posts, pages and authors: https://gist.github.com/billerickson/858ad34efdea9c75417b4217e33f8c3b#file-archive-php-L37
Any Genesis site with a sufficiently large registered user list (ie: membership sites) can be taken down by hitting random 404s since they’re uncached in most instances and trigger thousands of queries.
This patch is an easy win for performance.
This ticket was mentioned in Slack in #core by audrasjb. View the logs.
6 years ago
#5
@
6 years ago
- Owner changed from SergeyBiryukov to ianbelanger
- Status changed from reviewing to accepted
#6
@
6 years ago
- Keywords needs-testing added
I tested the patch and it does limit the number queries as intended, however it was throwing 2 PHP notices for each user due to the fact that $author = get_userdata( $author_id );
was moved after $posts = isset( $author_count[ $author->ID ] ) ? $author_count[ $author->ID ] : 0;
in the loop, so $author
was not yet defined.
45105.1.diff changes $posts = isset( $author_count[ $author->ID ] ) ? $author_count[ $author->ID ] : 0;
to $posts = isset( $author_count[ $author_id ] ) ? $author_count[ $author_id ] : 0;
to avoid throwing the PHP notices, while still limiting the number of queries.
Moving to 5.2, as this isn't a trunk regression.