次のことを試してみてください。単一のクエリではありませんが、大きな結合テーブルを使用した単一のクエリよりも優れていると思います。
public_addresses = Address.where(is_public: true)
# => get all public addresses
user_addresses = current_user.groups.includes(:group_members => :address).
# includes is to eager load records to avoid N+1 queries
flat_map{|g| g.group_members.map(&:address)}
# inner block returns array of addresses for each group
# flat_map converts the array of arrays to single level
# => get all addresses associated with the user
all_addresses = (public_addresses + user_addresses).uniq
# => remove duplicates
クエリを高速化するには、遅いクエリのインデックスを追加します。例えば
add_index :groups, :user_id
# this speeds up finding groups for a given user
add_index :group_members, :group_id
# this speeds up finding group_members for a given group
add_index :addresses, :group_member_id
# this speeds up finding addresses for a given group_member
その他のオプションは、テーブルuser_addresses
を使用することですjoin
user_addresses = Address.joins(group_member: group).where(groups: {user_id: current_user.id} )