我是PostgreSQL的新手。有没有办法改善以下查询的执行时间:
SELECT s.id, s.name, s.url,
(SELECT array_agg(p.url)
FROM (
SELECT url
FROM pages
WHERE site_id = s.id ORDER BY created DESC LIMIT 5
) as p
) as last_pages
FROM sites s
我没有找到如何将LIMIT
子句插入到聚合调用中,作为排序。
表created
中有timestamp
(site_id
)和integer
(pages
)的索引,但来自sites.id
的外键遗憾的是,pages.site_id
缺席。该查询旨在返回具有5个最近创建的页面的子列表的站点列表。
PostgreSQL版本是9.1.5。
答案 0 :(得分:3)
您需要首先考虑数据库管理系统。您还需要仔细考虑您从数据库中询问的内容。
这里的根本问题是,当顺序扫描速度提高时,您可能会发生大量单独的索引调用。您当前的查询为计划程序提供的灵活性非常小,因为您的子查询必须是相关的。
更好的方法是使用视图(内联或非内联)和窗口函数:
SELECT s.id, s.name, s.url, array_agg(p.url)
FROM sites s
JOIN (select site_id, url,
row_number() OVER (partition by site_id order by created desc) as num
from pages) p on s.id = p.site_id
WHERE num <= 5;
这可能会将大量索引扫描更改为单个大型顺序扫描。