当我使用此查询时,需要5分钟以上的时间,请给我其他建议
SELECT * FROM
( SELECT id,name,rownum AS RN$$_RowNumber FROM MILLION_1) INNER_TABLE where
RN$$_RowNumber > (V_total_count - V_no_of_rows)
ORDER BY RN$$_RowNumber DESC;
答案 0 :(得分:1)
尝试使用offset子句。
我有一个表,里面有大约1600万条记录,如果我只想要最后100,000行,我可以通过ORDER BY子句对它们进行ORDER,然后使用OFFSET子句,该子句基本上是说,首先读取这么多的行,返回任何数据之前。
select *
from SHERI; -- 15,691,544 Rows
select *
from SHERI
order by COLUMN4 asc
offset 15591444 rows; -- my math was bad, should have offset 15591544 rows to get just the last 100,000
FETCH FIRST和OFFSET子句是12c(docs)的新增功能
如果我们查看此查询下的计划,则可以看到数据库如何使其工作:
PLAN_TABLE_OUTPUT
SQL_ID 7wd4ra8pfu1vb, child number 0
-------------------------------------
select * from SHERI order by COLUMN4 asc offset 15591444 rows
Plan hash value: 3535161482
----------------------------------------------
| Id | Operation | Name | E-Rows |
----------------------------------------------
| 0 | SELECT STATEMENT | | |
|* 1 | VIEW | | 15M|
| 2 | WINDOW SORT | | 15M|
| 3 | TABLE ACCESS FULL| SHERI | 15M|
----------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("from$_subquery$_002"."rowlimit_$$_rownumber">15591444)
Note
-----
- Warning: basic plan statistics not available. These are only collected when:
* hint 'gather_plan_statistics' is used for the statement or
* parameter 'statistics_level' is set to 'ALL', at session or system level
“窗口排序”基本上转化为一种分析功能
答案 1 :(得分:0)
有一些very thorough answers at this similar question,但我会尽力使它们针对您的情况。
首先,当您说“最后10万行”时,您是什么意思?看起来您只想从未排序的查询中提取最后的10万行,但这没有多大意义。如果您想要100k个最近行,Oracle不能保证它们将出现在未排序查询的末尾。因此,您想按 something 排序,最后以最新的字母排序。
此外,查询速度慢的部分原因是您正在对 rownum 伪列进行排序/过滤,该伪列无法建立索引。对具有索引的列进行排序将大大加快此过程。因此,我猜您想按 id 列进行排序,该列可能是唯一/主键。
这是执行此操作的旧方法(11g及更早版本)。
select id, name
from (select id, name
from MILLION_1
order by id desc)
where rownum < 100000;
如果您使用的是12c或更高版本,则有一种更新的方法。
select id, name
from MILLION_1
order by id desc
fetch first 100000 rows only;