[buddypress-trac] [BuddyPress Trac] #7436: Very slow check_is_friend function

buddypress-trac noreply at wordpress.org
Wed Feb 8 03:35:28 UTC 2017

#7436: Very slow check_is_friend function
 Reporter:  januzi_pl     |       Owner:
     Type:  defect (bug)  |      Status:  new
 Priority:  low           |   Milestone:  2.7.5
Component:  Friends       |     Version:  2.7
 Severity:  major         |  Resolution:
 Keywords:  dev-feedback  |

Comment (by boonebgorges):

 Gah, I just left a comment, but my cookie died and I lost it :(

 @dcavins is correct that this improvement to group and friendship caching
 was meant to help in directories, and I think it's correct to say that it
 does help rather than hurt the majority of BP sites. But it's definitely
 not efficient in cases like this.

 @r-a-y - The goal of caching here is to avoid 20 extra db hits in member
 directories. Our current caching strategy is to first check the cache, and
 then to fall back to the database if nothing's found in the cache. This
 means that it's not possible to tell the difference between a cold cache
 and a non-friendship without hitting the database. (It's not practical to
 cache the non-friendship status of every set of non-friends.) We could
 reduce the number of db hits by doing some cache-warming at the beginning
 of the loop - sorta like `update_meta_cache`. But this only works well for
 successful friendships. We'd maybe have to cache non-friendships
 separately, perhaps non-persistently, which means it'd be impossible to
 avoid hitting the db altogether for all users.

 To clarify: Consider a site with three members: A, B, and C. The only
 friendship is between A and B. A is logged in and views `/members/`.
 Assume the cache is empty. After fetching the member IDs, we do something
 like this:

 // Check for uncached friendships.
 $member_ids = wp_list_pluck( $members_template->members, 'ID' );
 $uncached = array();
 foreach ( $member_ids as $member_id ) {
     // Don't check logged-in user.
     if ( $member_id === $loggedin_user_id ) {

     $cached = wp_cache_get( "$member_id:$loggedin_user_id",
 'bp_friends_friendship_pair' );
     if ( false === $cached ) {
         $uncached[] = $member_id;

 // Because the cache was empty, $uncached is [ B, C ]
 if ( $member_ids ) {
     $friendships = some_function_to_get_friendships_from_db( $member_ids
     foreach ( $friendships as $friendship ) {
         wp_cache_set( ... );

 Either (a) we cache every non-friendship, or (b) on the next pageload,
 `$member_ids` will be `[ C ]`, which will require a database hit.

 Maybe this is the best we can do to account for instances where users have
 many thousands of friends?

Ticket URL: <https://buddypress.trac.wordpress.org/ticket/7436#comment:8>
BuddyPress Trac <http://buddypress.org/>
BuddyPress Trac

More information about the buddypress-trac mailing list