sort_by is doing the sorting in ruby instead of the database, which is more inefficient. you change this by doing .order(:start_at) instead of .sort_by. Also, you want terms without a start_at to start first, so instead of using a sentinel value (that may not actually be first, cause some users put in crazy data), you can do .order(EnrollmentTerm.nulls(:first, :start_at)).  This applies to all three of these code changes.