sql - 查询最新记录的快速方法?

标签 sql performance oracle

我有一个这样的表:

USER |  PLAN |  START_DATE  |   END_DATE
1    |  A    |  20110101    |   NULL
1    |  B    |  20100101    |   20101231
2    |  A    |  20100101    |   20100505

在某种程度上,如果 END_DATEnull , 表示该用户当前拥有该计划。

我要查询的是:
(a) 他当前的计划,或 (b) 他最近参与的计划。我只需要为每个给定用户返回一行。

现在,我设法在使用联合和子查询时做到了这一点,但碰巧该表很大,而且效率不够高。
你们有没有更快的方法来查询?

谢谢,

[编辑]
这里的大多数答案都返回一个值。那是我的坏处。我的意思是为每个用户返回一个值,但一次返回所有用户。我已经调整了我可以的答案(并更正了问题),但只是为了将来引用而明确。

最佳答案

如果没有关于数据和表格的更多信息,这个问题有点难以回答。当您在评论中说您拥有所需的所有索引时,这些索引是什么?

此外,时间段是否相邻且不重叠?您能获取最新 START_DATE 的时间段吗?

查看 END_DATE 的问题是普通 B 树索引不会索引 NULL。因此,形式为 where end_date is nulll 的谓词不太可能使用索引。您可以将位图索引与列一起使用,因为这些类型的索引会索引空值,但由于位图索引的一些其他缺点,这可能并不理想。

由于上述原因,我可能会使用类似于以下查询的查询:

select user, plan, start_date, end_date
from (
  select 
    user, 
    plan, 
    start_date, 
    end_date, 
    row_number() over (partition by user order start_date desc) as row_num_1,
    row_number() over (partition by user order end_date desc nulls first) as row_num_2
  from user_table
  where user = :userid
)
where row_num_1 = 1

您可能可以使用 row_num_1row_num_2列这里取决于确切的要求。

或者
select user, plan, start_date, end_date
from (
  select 
    user, 
    plan, 
    start_date, 
    end_date, 
  from user_table
  where user = :userid
  order by start_date desc
)
where rownum = 1

无论您是尝试让所有用户回来还是只让一个用户回来,第一个查询都应该有效。第二个查询仅适用于一个用户。

如果您可以使用模式的更多详细信息(索引、开始/结束日期的含义)来扩充问题,您可能会得到更好的答案。

关于sql - 查询最新记录的快速方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6095928/

相关文章:

mysql - 过滤 SQL 结果?

java - 在 Java 中运行 MySQL 查询?

arrays - Bash:以随机索引访问大数组很慢

multithreading - excel多线程计算速度慢

c++ - EXEC SQL LOB WRITE APPEND 与轮询(先写、下写、最后写)

使用 Select Join 更新 MySQL

mysql - 如何通过一个 SQL 查询获取每个外键 ID 的最新数据集?

performance - CUDA内核: performance drops by 10x when increased loop count by 10%

java - 从java插入时间戳oracle列

java - 使用 Java/JDBC 时性能受到巨大影响