在oracle分页方面遇到一些麻烦。情况下:
表> 10亿行:
指数:
我需要一个获取第一个匹配的查询以及按Value排序的以下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中是否支持分页?
答案 0 :(得分:0)
您可以使用以下
SELECT * FROM
(SELECT Id, Classification, Value, ROWNUM Rank FROM Measurement WHERE Value >= 1234567890)
WHERE Rank <= 2000
order by Rank
您无需在子查询中订购。根本没必要。 以上不是分页,而是我想的第一页。
答案 1 :(得分:0)
请尝试更多选项
SELECT *
FROM( SELECT /*+ FIRST_ROWS(2000) */
Id,
Classification,
Value,
ROW_NUMBER() OVER (ORDER BY Value) AS rn
FROM Measurement
where Value > 1234567889
)
WHERE rn <=2000;
Update1: - 强制使用Value.Here IDX_ON_VALUE是衡量值中索引的名称
SELECT * FROM
(SELECT /*+ INDEX(a IDX_ON_VALUE) */* FROM Measurement
a WHERE value >=1234567890 )
ORDER BY a.Value ASC)
WHERE ROWNUM <= 2000
答案 2 :(得分:0)
不确定你是否为你的问题找到了解决方案,但是我要花两分钱:
第一个查询将无法满足您的要求,因为它将获取满足您查询的2000个随机记录,然后按顺序执行。
来到第二个查询:
Oracle将首先执行第二个查询,然后只移动到外部查询。因此,只有在执行内部查询后才会应用rownum过滤器。
你可以尝试以下方法,做INDEX FAST FULL SCAN
,我已经在一张276万行的桌子上进行了测试,它的成本低于其他方法:
SELECT * from Measurement
where value in ( SELECT VALUE FROM
(SELECT Value FROM Measurement
WHERE Value >= 1234567890 ORDER BY Value ASC)
WHERE ROWNUM <= 2000)
希望它有助于
Vishad
答案 3 :(得分:0)
我想我喜欢潜在的解决方案。但是,这不是一个查询。
declare
cursor c is
SELECT * FROM Measurement WHERE Value >= 1234567890 ORDER BY Value ASC;
l_rec c%rowtype;
begin
open c;
for i in 1 .. 2000
loop
fetch c into l_rec;
exit when c%notfound;
end loop;
close c;
end;
/