An activity log has the potential for a very large number of records since it usually has a mix of the current user's activity and all their friends. If you are joining various tables and a user has 100s of friends that's potentially a lot of data being pulled out.
One approach is to denormalise the data and treat it as one big log where all entries that should appear on a user's activity log page to be stored in the activity log table against that user. For example if User A has two friends, User B and User C, when User A does something three activity log records are created:
record 1: "I did this" log for user A
record 2: "My friend did this" log for user B
record 3: "My friend did this" log for user C
You'll get duplicates, but it doesn't really matter. It's fast to select since it's from one table and indexed on just the user ID. And it's likely you'll housekeep an activity log table (i.e. delete entries over 1 month old).
The activity log table could be something like:
-id
-user_id (user who's activity log this is)
-action_user_id (user who took the action, or null if same as user_id)
-activity_type
-date
To select all recent activity logs for a single user is then easy:
SELECT * from activity_log WHERE user_id = ? ORDER by date DESC LIMIT 0,50
To make this approach really efficient you need to have enough information in the single activity log table to not need any further selects. For example you may store the raw log message, rather than build it on the fly.