我有两张桌子:
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)
两者都给了我所需的数据。我的问题是我应该使用哪一个?
是否有任何规则表明你应该通过OR中的OR外键将组中的主键用于OR?
答案 0 :(得分:6)
鉴于您已经完成左连接,您应该使用第二个查询作为marks.user_id可以为null
答案 1 :(得分: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
答案 2 :(得分:2)
我建议您使用第二个,因为主键索引与任何其他重复索引之间存在轻微的性能差异。您对该表的最常见查询很可能是查明用户是否在某个标记中,并且除非marks.user_id可以为null,否则该查询将执行得很快。
答案 3 :(得分: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表示它使用filesort作为用户表,并且表中没有使用任何键,当我运行以下内容时:
DESCRIBE SELECT name, class, SUM(mark) AS total FROM user
LEFT JOIN marks ON marks.user_id = user.id
GROUP BY user.id;
现在MySQL说它使用两个表的键(而不是使用filesort)。因此我认为,第二个应该是推荐的做法,因为filesort可能会降低性能。
答案 4 :(得分:0)
因为主键是唯一索引。 group by(主键)
未减少结果中的行数
所以我认为你可以使用group by(外键)