【问题标题】:Select physically last record without ORDER BY选择没有 ORDER BY 的实际最后一条记录
【发布时间】:2018-01-26 16:20:14
【问题描述】:

我继承的一个应用程序是面向 PostgreSQL 表中的“自然记录流”,并且有一个 Delphi 代码:

query.Open('SELECT * FROM TheTable');
query.Last();

任务是获取最后一个表记录的所有字段。我决定以更有效的方式重写此查询,如下所示:

SELECT * FROM TheTable ORDER BY ReportDate DESC LIMIT 1

但它破坏了所有工作流程。一些 ReportDate 记录结果为 NULL。该应用程序实际上是以表格中“自然”的记录顺序为导向的。

如何在没有 ORDER BY 的情况下有效地进行物理最后一条记录选择?

【问题讨论】:

  • 为什么不加WHERE ReportDate IS NOT NULL
  • 你看过这个QA吗? stackoverflow.com/questions/20050341/… - 如果没有 ORDER BY,则返回结果的顺序是 undefined - 没有“自然顺序” - 它可能会根据当前的月相或您曾经改变过如果您的 DBMS 将行重新排序以提高效率,请执行表垃圾收集。
  • @Dai:谢谢,我没看到那个QA。那里的关键短语是“可能会随着时间而改变”。所以,我会尽量坚持使用 ORDER BY。

标签: postgresql


【解决方案1】:

要选择物理上的最后一条记录,您应该使用ctid - 元组 id 来获取最后一条 - 只需选择 max(ctid)。比如:

t=# select ctid,* from t order by ctid desc limit 1;
  ctid  |               t               
--------+-------------------------------
 (5,50) | 2017-06-13 11:41:04.894666+00
(1 row)

不用order by

t=# select t from t where ctid = (select max(ctid) from t);
               t               
-------------------------------
 2017-06-13 11:41:04.894666+00
(1 row)

值得知道的是,只有在顺序扫描之后才能找到 ctid。因此在大型数据集上检查最新的物理行会很昂贵

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-08
    • 2019-08-31
    • 1970-01-01
    • 2019-06-29
    • 2021-11-26
    • 1970-01-01
    • 2011-08-30
    相关资源
    最近更新 更多