【发布时间】:2014-12-18 21:27:56
【问题描述】:
在使用 oracle 分页时遇到了一些问题。案例:
超过 10 亿行的表:
- 测量(Id 编号、分类 VARCHAR、值 NUMBER)
索引:
- 开启测量(值)
我需要一个查询来获取第一个匹配项以及按值排序的以下 2000 个匹配项。我也想使用索引。
第一个想法:
SELECT * FROM Measurement WHERE Value >= 1234567890
AND ROWNUM <= 2000 ORDER BY Value ASC
结果: 该查询只返回它可以在表中找到的前 2000 个案例,从顶部开始,其中 Value 大于或等于 1234567890,然后对该结果集进行升序排序。
第二个想法:
SELECT * FROM
(SELECT * FROM Measurement WHERE Value >= 1234567890 ORDER BY Value ASC)
WHERE ROWNUM <= 2000
结果: Oracle 不理解 ROWNUM 应该限制内部查询的数量,因此 oracle 决定首先获取 Value 大于或等于 1234567890 的所有行,然后在返回前 2000 行之前对该巨大的结果集进行排序。因为 Oracle 猜测表中的大部分数据都会被返回,所以它也忽略了对索引的任何使用。
这些方法都不可接受,因为第一个给出错误的结果,而第二个需要几个小时。
Oracle 完全支持分页吗?
【问题讨论】:
-
第一个查询肯定不行。第二个查询,删除 hte order by,并将其移至外部选择。尝试在内部查询中添加索引提示并运行解释计划。
-
你的表分区了吗?第一个给出了不正确的结果,因为逻辑不正确。第二个很慢,因为你做的是正确的事情......查询的解释计划是什么?您无需分页 10 亿行。没有人会读到它们,所以不要……
-
您不能将 ORDER BY 移动到外部 SELECT @OldProgrammer;你会得到与第一个查询相同的结果。
-
Ben:基本上我想看看上面的测量值,包括 1234567890 测量值。但仅限于 2000 行。看起来不像是一个不寻常的案例。
-
如果您只想要前 2k 条记录,则无需分页!全扫描根本不是我所期望的。由于 ROWNUM 限制,至少我希望有一个计数停止键,所以你确定吗?是否启用了分区?`
标签: oracle oracle11g pagination rownum