我从其他来源找到了一些解决方案,但似乎没有一个对我有效执行。我正在使用德比,我目前的解决方案需要一分钟才能执行!
我正在尝试查找属于给定艺术家的歌曲和专辑的数量,并在艺术家姓名和ID旁边的2个单独列中显示这些数字。例如:
ID Name Songs Albums
425 J. Smith 0 0
314 A. Payne 32 3
412 K. Thomas 423 35
艺术家表有artist_id,歌曲表有song_id和album_id,专辑表有album_id和artist_id。这些表格并不小。艺术家有大约1,100首唱片,歌曲大约有73,000张,而专辑大约有7000张。
这是我目前的解决方案:
select ar.artist_id, ar.artist_name, count(s.song_id), count(distinct(al.album_id))
from artist ar left outer join
(album al inner join song s
on al.album_id = s.album_id)
on ar.artist_id = al.artist_id
group by ar.artist_id, ar.artist_name
有没有办法让这个查询表现得更好? ID列是各自表中的主键,因此如果我理解正确,它们应该已经在derby中编入索引。
答案 0 :(得分:3)
此查询使用派生表来获取歌曲和专辑计数
select ar.artist_id, ar.artist_name,
coalesce(t1.song_cnt,0), coalesce(t2.album_cnt,0)
from artist ar left join (
select artist_id, count(*) song_cnt
from song group by artist_id
) t1 on t1.artist_id = ar.artist_id
left join (
select artist_id, count(*) album_cnt
from album group by artist_id
) t2 on t2.artist_id = ar.artist_id
您可能希望查看将计数本身存储在数据库中并使用触发器更新它们。
答案 1 :(得分:2)
如果您想在一个查询中执行此操作,我认为您最好使用子查询并加入这些查询。或者,您可以将其分解为几个小查询并让您的应用程序执行连接而不是MySQL ...它肯定会更快地执行小查询然后循环结果来构造输出而不是递归你正在进行的内部联接。
(SELECT artist_id,COUNT(id)AS numAlbums FROM album GROUP BY artist_id) (SELECT album_id,COUNT(id)AS numSongs FROM song GROUP BY album_id)
最后......我想抛弃它,虽然当你第一次使用数据库设计时,他们会谈论规范化,就像它是法律一样。但是当你在职业生涯中走得更远的时候,你实际上已经了解了非规范化,有时预先计算的列(例如你的计数)是可接受的,也是快速性能所必需的。