我在PostgreSQL数据库中有这3个表:
基本上每位艺术家都有多张专辑,每张专辑都有多首歌曲。
我的查询正确地返回了25个不同的artist.id,他们的歌曲的标题以“The”开头,以相册的年份排序:
SELECT id
FROM (
-- Remove the duplicate artists
SELECT DISTINCT ON (a.id) id, row
FROM (
-- Get all matching artists
-- This is slow because there is no limit
SELECT
artist.id,
row_number() OVER(ORDER BY album.year DESC) as row
FROM artist
LEFT JOIN album ON album.artist_id = artist.id
LEFT JOIN song ON song.album_id = album.id
WHERE song.title ilike 'The %'
ORDER BY album.year DESC
) as a
) as b
ORDER BY row
LIMIT 25
然而,它是缓慢且低效的,因为最里面的查询没有LIMIT,因此它将在整个表中搜索所有可能的匹配。理想情况下,当找到25个不同的artist.id时,它会停止搜索。
可以重写或优化此查询以更快地执行吗?
我认为window functions可以在这里加快速度,但我无法找到有用的东西。
谢谢!
答案 0 :(得分:1)
select id, year
from (
SELECT DISTINCT ON (artist.id) artist.id, album.year
FROM artist
inner JOIN album ON album.artist_id = artist.id
inner JOIN song ON song.album_id = album.id
WHERE song.title ilike 'The %'
ORDER BY artist.id, album.year DESC
) s
order by year desc
LIMIT 25
song.title
上的索引可以在ilike表达式以%
答案 1 :(得分:0)
试试这个,应该比当前查询更快地工作
SELECT
artist.id,
MAX( album.year ) as latest_album_date
FROM
artist
JOIN album ON album.artist_id = artist.id -- JOIN, not LEFT JOIN
JOIN song ON song.album_id = album.id -- Since you have song.title in WHERE clause, it makes no sense to make these as a LEFT JOIN
WHERE
song.title ilike 'The %'
GROUP BY
artist.id
ORDER BY
latest_album_date DESC
limit 25;
答案 2 :(得分:0)
试试这个,
Select id, year
from (
SELECT DISTINCT ON (artist.id) artist.id, album.year
FROM artist
rightJOIN album ON album.artist_id = artist.id
left JOIN song ON song.album_id = album.id
WHERE song.title ilike 'The %'
ORDER BY artist.id, album.year DESC
) s
order by year desc
LIMIT 25