oracle千万数据中较快速查找满足max条件的数据行

场景

假设我们有这样的一个访问记录表accessTable,记录项分别为用户唯一标识(userId)、访问时间(visitTime)、访问时上报的版本信息(ver)。需求为查询每个用户最近一次访问时上报的版本是什么,环境是在oracle下。本人非DBA,有问题一定要指出来啊。

思路一

使用oracle的分析函数。具体函数使用见这里

[java]
SELECT *
FROM (SELECT t.userId,
t.visitTime,
t.ver,
Row_number()
OVER(
partition BY t.userId
ORDER BY t.visitTime DESC) rk
FROM accessTable t) rank_tab
WHERE rank_tab.rk = 1
[/java]

这里的思路是通过row_number分析函数为数据排名,排名按用户标识分组,并按访问时间由大到小。实际运行时此种方式仍速度极慢。

思路二

这个思路是从一个同事处得来的,首先在此表示感谢,他的实现思路是利用ORACLE的rowid实现。其实我们只需要找到每个userId的最大访问时间的数据行。

[java]
SELECT acc_tab.*,acc_tab.rowid
FROM accessTable acc_tab,
(SELECT Substr(tr_tab.time_rowid, 15) rk_rowid
FROM (SELECT t.userId,
Max(To_char(t.visitTime, ‘yyyymmddhh24miss’)
|| t.rowid) AS time_rowid
FROM accessTable t
GROUP BY t.userId) tr_tab)r_tab
WHERE acc_tab.rowid = r_tab.rk_rowid
[/java]

实现时是将日期字符串和该条记录对应的rowid串起来拼出一个长串,对这个长串来求最大,求出最大的字符串的同时我们可以从字符串中拆出对应的rowid,然后通过rowid关联从而快速的得到满足条件的记录,这种方法在实际环境下效率是不错的。拼串时要注意拼的内容,字符串比较会认为22比111大。

由于水平有限,非专业DBA,错漏难免,如有意见和建议请一定及时指出,防止水平有限误导他人。