#5407 closed enhancement (invalid)
Improve wp_list_authors efficiency
| Reported by: |
|
Owned by: | |
|---|---|---|---|
| Milestone: | Priority: | low | |
| Severity: | normal | Version: | 2.3.1 |
| Component: | Users | Keywords: | needs-patch |
| Focuses: | performance | Cc: |
Description
wp_list_authors() makes multiple queries per registered user. For example, if a blog has 50 registered users, wp_list_authors() will make over 100 queries, even if there are only a few users who can write posts.
Alexander Concha developed the attached patch which does it all with only one query total (two if "show_fullname" is enabled). However, he questions if this change belongs in the WP core. I think it does because it's such a vast improvement over the current extremely inefficient code.
Attachments (2)
Change History (17)
#3
@
17 years ago
I would say this should be a pretty high priority.
I just ran into an instance with a site that has over 13,000 registered subscribers, and wp_list_authors in its current state wants to use over 80Mb of memory.
#4
@
17 years ago
- Milestone changed from 2.9 to 2.8
If it works, then it works and should be included.
#5
@
17 years ago
Why not include it early for 2.8, so that if there are any problems, the change can either be reverted or corrected?
#6
@
17 years ago
- Milestone changed from 2.8 to Future Release
Pushing due to schedule. Can evaluate in next release cycle.
#7
@
17 years ago
- Keywords needs-patch added; has-patch 2nd-opinion removed
- Priority changed from normal to low
there are still inefficiencies in the suggested patch. the correct one to use is:
if ( $show_fullname ) {
$author_name_field = "CASE
WHEN TRIM(CONCAT(COALESCE(meta_first_name.meta_value, ''), COALESCE(meta_last_name.meta_value, ''))) <> ''
THEN
TRIM(CONCAT(COALESCE(meta_first_name.meta_value, ''), COALESCE(meta_last_name.meta_value, '')))
ELSE
$wpdb->users.display_name
END"
$author_name_join = "
LEFT JOIN $wpdb->usermeta as meta_first_name ON meta_first_name.user_id = $wpdb->users.ID AND meta_first_name.meta_key = 'firstname'
LEFT JOIN $wpdb->usermeta as meta_last_name ON meta_last_name.user_id = $wpdb->users.ID AND meta_last_name.meta_key = 'lastname'
";
} else {
$author_name_field = "$wpdb->users.display_name"
$author_name_join = "";
}
$authors = $wpdb->get_results("
SELECT $wpdb->users.ID, $wpdb->users.user_nicename, COUNT($wpdb->posts.ID) as author_count, $author_name_field as author_name
FROM $wpdb->users
" . ( !$hide_empty ? "LEFT " : '' ) . "JOIN $wpdb->posts ON $wpdb->posts.post_author = $wpdb->users.ID
$author_name_join
" . ( $exclude_admin ? "WHERE $wpdb->users.user_login <> 'admin' " : '' ) . "
GROUP BY $wpdb->users.ID
ORDER BY $wpdb->users.display_name
");
It'll then get all of the needed details in one go, without the clutter (why is the private_posts_sql in there anyway?).
However, it's mostly pointless to do so without editing a few more functions. Specifically, get_author_feed_link() will then go on for a rampage because it'll get each author individually. an extra param (user_nicename) is needed to the function, in order to pass it to get_author_posts_url().
the rest amounts to needing to rewrite the function as needed.
#10
@
16 years ago
Patch submitted to a related ticket including Denis-de-Bernardy's suggested code above. See #10329.
#14
@
12 years ago
- Component changed from Optimization to Users
- Focuses performance added
- Milestone Future Release deleted
- Resolution set to invalid
- Status changed from new to closed
None of this is raw SQL anymore — it uses get_users() for caching purposes.
Improve wp_list_authors() efficiency