How to obtain active genres in activerecord?
I am using Rails 3 and postgresql. I have the following genres: rock, ambience, alternative, house.
I also have two users registered. One has rock and the other house, as their genres. I need to return rock and house genre objects.
I found two ways to do this. One is using group:
Genre.group('genres.id, genres.name, genres.cached_slug, genres.created_at, genres.updated_at').joins(:user).all
And the other using DISTINCT:
Genre.select('DISTINCT(genres.name), genres.cached_slug').joins(:user)
Both return the same desired results. But which one is better performance wise? Using group() looks messy since I have to indicate all the fields in the Genre table otherwise I'll get errors as such:
ActiveRecord::StatementInvalid: PGError: ERROR: column "genres.id" must appear in the GROUP BY clause or be used in an aggregate function
: SELECT genres.id FROM "genres" INNER JOIN "users" ON "users"."genre_id" = "g开发者_开发知识库enres"."id" GROUP BY genres.name
A DISTINCT
and GROUP BY
usually generate the same query plan, so performance should be the same across both query constructs.
Since you're not using any aggregate functions, you should use the one that makes the most sense in your situation, which I believe is this one:
Genre.select('DISTINCT(genres.name), genres.cached_slug').joins(:user)
This will be more clear when trying to read your code later and remember what you did here and, as you pointed out, is much less messy.
Update
It depends on the version of Postgresql you are using. Using versions < 8.4, GROUP BY
is faster. With version 8.4 and later, they are the same.
精彩评论