5

我有两张桌子:

user
=======
id
name
class

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

用户表包含用户(学生)的详细信息 分数表包含具有学科 ID 的不同学科的学生的分数

我想从这些表中获取姓名、班级和总分。

我有两个疑问:

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)

两者都给了我所需的数据。我的问题是我应该使用哪一个?

是否有任何规则说您应该在 group by 中使用主键或在 group by 中使用外键或类似的东西?

4

5 回答 5

7

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

于 2013-07-22T09:43:49.793 回答
3

您应该使用按主键的 2 版本分组。一般来说,最好根据主表的列而不是连接的列来进行 order 和 group by 语句。如果您对连接表列进行排序或分组,MySQL 必须根据您的数据大小创建临时表,这些表很容易进入磁盘并最终导致严重的性能瓶颈。

为这两个查询运行这些解释,看看我在说什么:

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;

同样可以在这里找到:http ://sqlfiddle.com/#!2/a8ece/6

于 2013-07-22T09:50:49.110 回答
2

实际上,我建议您使用第二个,因为主键索引和任何其他重复索引之间的性能略有不同。您对该表最常见的查询很可能是查明用户是否在某个标记中,并且该查询将执行得很快,除非marks.user_id 可以为空。

于 2013-07-22T09:47:01.643 回答
1

当我运行以下 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 说它对用户表使用文件排序,并且该表没有使用任何键,当我运行以下命令时:

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

现在 MySQL 说它对两个表都使用键(而不是使用文件排序)。因此我认为,第二个应该是推荐的做法,因为文件排序可能会降低性能。

于 2013-07-22T10:06:28.617 回答
0

因为主键是唯一索引。分组方式(主键)

结果中的行数没有减少

所以我认为您可以使用分组方式(外键)

于 2013-07-22T09:43:25.100 回答