最高效可靠的方式是ORDER BY updated_at DESC LIMIT 1且updated_at字段必须建降序索引,并加上WHERE updated_at IS NOT NULL过滤空值,否则可能返回任意记录或NULL数据。

直接用 ORDER BY updated_at DESC LIMIT 1(或对应数据库的等价写法)是最高效、最可靠的方式,前提是 updated_at 字段已建索引。
为什么不能只写 LIMIT 1 不排序?
数据库不保证物理存储顺序与业务时间顺序一致。没 ORDER BY 时,LIMIT 1 返回的是任意一条——可能是最早插入的、主键最小的、甚至缓存里碰巧在前的记录,完全不是“最近更新”。尤其在 InnoDB 中,行物理位置受插入/删除/页分裂影响极大,结果不可预测。
常见错误现象:SELECT * FROM logs LIMIT 1 在测试环境看似正常,上线后数据量增长、表重建后结果突变,排查成本远高于一开始加排序。
updated_at 字段必须建索引,且推荐带方向
没索引时,ORDER BY updated_at DESC LIMIT 1 会触发全表扫描 + 内存排序,哪怕只取 1 条,也要读完全部百万行再排序,响应从毫秒级变成秒级。
正确建法(以 PostgreSQL / MySQL 8.0+ 为例):
CREATE INDEX idx_logs_updated_at_desc ON logs(updated_at DESC);
原因:
- MySQL 5.7+ 和 PostgreSQL 支持在索引定义中指定
DESC,优化器能直接利用索引逆序结构跳到最大值位置,避免额外排序步骤 - 如果只建
CREATE INDEX idx_logs_updated_at ON logs(updated_at),多数情况下也能走索引,但某些版本或复杂查询下可能仍触发Using filesort - Oracle 12c+ 和 SQL Server 对索引方向不敏感,但显式声明更利于语义表达和未来迁移
NULL 值会破坏排序结果,必须显式过滤
updated_at IS NULL 的记录在 DESC 排序中默认排在最前面(SQL 标准行为),你可能拿到一条“时间为空”的脏数据,而非真正最新的一条。
务必加上条件:
SELECT * FROM logs WHERE updated_at IS NOT NULL ORDER BY updated_at DESC LIMIT 1;
补充说明:
- MySQL 不支持
NULLS LAST,所以不能靠排序参数兜底,WHERE过滤是唯一稳妥方式 - PostgreSQL 可写
ORDER BY updated_at DESC NULLS LAST,但依然建议加WHERE updated_at IS NOT NULL—— 明确业务语义,且避免因统计信息不准导致执行计划退化 - 如果业务允许用默认时间兜底(比如 '1970-01-01'),可用
COALESCE(updated_at, '1970-01-01'),但要注意该写法会让索引失效,除非你建函数索引(如 PostgreSQL 的CREATE INDEX ... ON logs(COALESCE(updated_at, '1970-01-01')))
别用 MAX(updated_at) 子查询,除非真需要所有同时间记录
写成 SELECT * FROM logs WHERE updated_at = (SELECT MAX(updated_at) FROM logs) 看似自然,但有两个硬伤:
- 如果有两条记录
updated_at完全相同(比如批量更新、微秒级时间戳截断),会返回多条,而你只想要“一条” - 子查询需全表扫一次找最大值,外层再扫一次匹配,无索引时是 2×O(n);有索引时虽能快些,但仍比单次索引定位多一次 B-Tree 查找
- 若字段未建索引,性能差距更明显:前者是 2 次全表扫描,后者是 1 次全表扫描 + 排序
如果你确实需要“同时间只取 ID 最大的那条”,可改用:
SELECT * FROM logs WHERE updated_at = (SELECT MAX(updated_at) FROM logs) ORDER BY id DESC LIMIT 1;
但这就已经比直接 ORDER BY updated_at DESC, id DESC LIMIT 1 多绕了一层,且丧失了索引直取优势。
最容易被忽略的点:复合查询场景下,比如“查用户 A 最近一条已完成订单”,此时单列 updated_at 索引无效,必须建联合索引,如 (user_id, status, updated_at DESC),且字段顺序不能错——user_id 必须在最左,否则索引无法命中。










