How to make this WP_Query run faster on a WordPress website?

Two bits of advice:

  1. Most importantly, database query performance hinges on how many rows match the query, not how many rows you want. Even if you’re only asking for 5 posts, the database could have to query and sort a million results in order to give you those 5. Say I gave you a 100,000 index cards, each with a different random number on it, and I asked you to pull out the 5 biggest numbers. I may only want 5, but you still have to look at all 100,000 in order to figure out which 5 those are. Bottom line, you need to get the result set down, and often times the easiest way to do that in this scenario is to add a date query to the WP_Query arguments. If you only want the 7 or 5 most recent posts, and you know that they will always be from the last month, add a date query restricting the query to the last month: 'date_query' => [ [ 'after' => '-30 days' ] ],. Go even more recent if you can, or pull it back to a wider range if you must. You’ll be shocked at how much this can help! I gave a WordCamp talk that was pretty heavy on this topic, if you’re interested.
  2. Less important, but still a best practice, NOT IN() queries are not optimal. When possible, it’s preferable to query for additional posts and then remove them using PHP. In this case, you’d query for 12 posts in your second query, then use something like PHP’s array_filter() to exclude the 7 you don’t want duplicated.