使用Postgresql进行高效的最新记录查询

She*_*oss 49 sql postgresql subquery distinct

我需要做一个大问题,但我只想要最新的记录.

对于单个条目,我可能会做类似的事情

SELECT * FROM table WHERE id = ? ORDER BY date DESC LIMIT 1;
Run Code Online (Sandbox Code Playgroud)

但是我需要为大(数千个条目)数量的记录提取最新记录,但只记录最新条目.

这就是我所拥有的.效率不高.我想知道是否有更好的方法.

SELECT * FROM table a WHERE ID IN $LIST AND date = (SELECT max(date) FROM table b WHERE b.id = a.id);
Run Code Online (Sandbox Code Playgroud)

int*_*tgr 49

如果您不想更改数据模型,可以使用DISTINCT ON从表"b"中获取"a"中每个条目的最新记录:

SELECT DISTINCT ON (a.id) *
FROM a
INNER JOIN b ON a.id=b.id
ORDER BY a.id, b.date DESC
Run Code Online (Sandbox Code Playgroud)

如果你想避免查询中的"排序",添加这样的索引可能对你有帮助,但我不确定:

CREATE INDEX b_id_date ON b (id, date DESC)

SELECT DISTINCT ON (b.id) *
FROM a
INNER JOIN b ON a.id=b.id
ORDER BY b.id, b.date DESC
Run Code Online (Sandbox Code Playgroud)

或者,如果要以某种方式对表"a"中的记录进行排序:

SELECT DISTINCT ON (sort_column, a.id) *
FROM a
INNER JOIN b ON a.id=b.id
ORDER BY sort_column, a.id, b.date DESC
Run Code Online (Sandbox Code Playgroud)

替代方法

但是,所有上述查询仍然需要从表"b"中读取所有引用的行,因此如果您有大量数据,它可能仍然太慢.

您可以创建一个新表,它只为每个表保存最新的"b"记录a.id- 或者甚至将这些列移动到"a"表本身.

  • 这个家伙全力以赴:http://stackoverflow.com/a/7630564/1699320 (2认同)

man*_*nji 36

这可能更有效.区别:表b的查询只执行一次,每行执行相关的子查询:

SELECT * 
FROM table a 
JOIN (SELECT ID, max(date) maxDate
        FROM table
      GROUP BY ID) b
ON a.ID = b.ID AND a.date = b.maxDate
WHERE ID IN $LIST 
Run Code Online (Sandbox Code Playgroud)

  • 为什么您认为联接效率低下,特别是考虑到它仅联接一行? (2认同)
  • 在测试完这两种方法之后,对我来说max(date)比DISTINCT ON快3倍。 (2认同)
  • 这真的是一个很好的解决方案!非常感谢!我的查询时间从 470 毫秒减少到 95 毫秒。我使用 max(id) 作为最后一行标识符。所以它可以比日期时间比较更有效。 (2认同)

unk*_*own 6

你怎么看待这件事?

select * from (
   SELECT a.*, row_number() over (partition by a.id order by date desc) r 
   FROM table a where ID IN $LIST 
)
WHERE r=1
Run Code Online (Sandbox Code Playgroud)

我过去经常用它