当我试图从oracle11g数据库中获取带有分页的对象列表时,我面临着一个很大的性能问题。
据我所知,在oracle11g中实现分页的唯一方法是:示例: page=1,size=100
SELECT * FROM
(
SELECT pagination.*, rownum r__ FROM
(
select * from "TABLE_NAME" t
inner join X on X.id = t.id
inner join .....
where ......
order
) pagination
WHERE rownum <= 200
)
WHERE r__ > 100此查询中的问题是,从表"TABLE_NAME“获取数据的最内部查询返回大量数据,并导致整个查询花费8秒(应用where子句后,大约有200万条记录返回,其中包含9或10个join子句)。
这样做的原因是,最内部的查询是获取所有符合where子句的数据,然后第二个查询获取200行,第三个查询排除前100行以获取我们需要的第二页数据。
难道没有一种方法可以在一个查询中做到这一点,通过一种方式来获取我们需要的第二个页面的数据,而不必执行所有这些步骤并导致性能问题吗?
谢谢你!!
发布于 2021-09-02 14:53:42
这取决于您的排序选项(order by ...):由于您的order by子句,数据库需要在应用外部where rownum<200之前对整个数据集进行排序。
如果您删除order by子句,它将只获取200行。在某些情况下,oracle可以避免排序操作(例如,如果oracle可以使用某些索引以所需的顺序获取请求的数据)。顺便说一句,Oracle在rownum<N谓词的情况下使用了优化的排序操作:它不会对整个数据集进行排序,而只是获得前N条记录。
可以使用排序跟踪事件:alter session set events '10032 trace name context forever, level 10';更深入地研究排序操作
此外,有时最好使用像这样的分析函数
select *
from (
select
t1.*
,t2.*
,row_number()over([partition by ...] order by ...) rn
from t1
,t2
where ...
)
where rn <=200
and rn>=100因为在某些特定情况下,Oracle可以将查询转换为将排序和排序过滤器谓词推送到最早的步骤。
https://stackoverflow.com/questions/69032374
复制相似问题