简体   繁体   中英

GROUP BY foreign key or primary key?

I have two tables :

user
=======
id
name
class

marks
=======
id
user_id
sub_id
mark

user table contains the details of user (student) marks table contains the marks of a student in different subjects with subject id

I want to fetch name, class and total marks from these tables.

I have two queries :

1. SELECT name, class, SUM(mark) AS total FROM user
   LEFT JOIN marks ON marks.user_id = user.id
   GROUP BY marks.user_id
   ///Here in GROUP BY I have used foreign key (marks.user_id)

2. SELECT name, class, SUM(mark) AS total FROM user
   LEFT JOIN marks ON marks.user_id = user.id
   GROUP BY user.id
   ///Here in GROUP BY I have used primary key (user.id)

Both gives me required data. My question is which one should I use?

Is there any rule which says you should use primary key in group by OR foreign key in group by OR something like that ?

鉴于您已经完成了左连接,您应该使用第二个查询作为marks.user_id可以为null

You should use the 2 version grouping by the primary key. In general it's better to have order and group by statements based on column(s) of the main table and not the joined ones. If you do order or group by on joined table columns MySQL has to do create temporary tables which based on your datasize could easily go to disk and end up significant performance bottleneck.

Run these explains for the two query to see what I was talking about:

EXPLAIN SELECT name, SUM(mark) AS total FROM users
   LEFT JOIN marks ON marks.user_id = users.id
   GROUP BY marks.user_id;

EXPLAIN SELECT name, SUM(mark) AS total FROM users
   LEFT JOIN marks ON marks.user_id = users.id
   GROUP BY users.id;

Same can be found here: http://sqlfiddle.com/#!2/a8ece/6

Acutally i suggest you to use the second one because there is a slightly performance difference between a primary key index and any other duplicate index. It's very likely that your most common query into that table would be to find out if a user is in a certain marks, and that query will perform fast unless marks.user_id can be null.

When I ran the following SQL:

DESCRIBE SELECT name, class, SUM(mark) AS total FROM user
LEFT JOIN marks ON marks.user_id = user.id
GROUP BY marks.user_id;

MySQL said it uses filesort for user table and no keys has been used for the table, and when I ran the following:

DESCRIBE SELECT name, class, SUM(mark) AS total FROM user
LEFT JOIN marks ON marks.user_id = user.id
GROUP BY user.id;

Now MySQL said it uses keys for both the tables (instead of using filesort). Thus I think, the second one should be the recommended practice as filesort may degrade performance.

because the primary key is unique index. group by(primary Key)

not reduced number of line in your result

so i think you can use group by(foreign key)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM