4

我的 PostgreSQL 数据库中有这 3 个表:

  • 艺术家:身份证,姓名
  • 专辑: id,标题,年份,artist_id
  • 歌曲: id,标题,album_id

基本上每个艺术家都有多张专辑,每张专辑都有多首歌曲。

我的查询正确返回了 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

然而,它是缓慢且低效的,因为最里面的查询没有限制,因此它将搜索整个表以查找所有可能的匹配项。理想情况下,当找到 25 个不同的艺术家 ID 时,它会停止搜索。

可以重写或优化此查询以更快地执行吗?

我认为窗口函数可以在这里加快速度,但我一直无法找出可行的方法。

谢谢!

4

3 回答 3

2
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

当 ilike 表达式确实以 a 开头时,索引 onsong.title会有所帮助%

于 2013-04-19T19:38:57.097 回答
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
于 2013-04-20T10:43:00.637 回答
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;

SQLFIDDLE

于 2013-04-20T04:22:52.133 回答