我想从一张非常大的表中检索(100
)最近的日期。这似乎很容易,但是使用这样的东西;
SELECT *
FROM (
SELECT *
FROM [table] tbl
WHERE [some conditions]
ORDER BY tbl.date
)
WHERE ROWNUM < 100;
效率非常低,因为整个表都是读取和排序的。
最近的日期可能(但不能保证)在表的末尾。现在,出于性能原因,我想采取f.e.表的最后1000行满足设置条件并处理它们,而不访问巨大的表的其余部分。
我想知道是否可以通过优化器提示或其他方式使SQL(或PL / SQL)代码从文件末尾开始读取表,并让它停止查询只要选择(fe)1000
行?(与将WHEN ROWNUM < 1000
添加到简单选择时查询停止的方式相同)
答案 0 :(得分:0)
如果tbl.date
上有索引且(此列不可为空,或者您指定WHERE子句中只要不是空值)并且统计信息是最新的,那么索引应该是使用。
在大多数情况下,这种查询会获得INDEX FULL SCAN ASC/DESCENDING
访问路径,如下所示:
SQL> CREATE TABLE TEST AS
2 (SELECT SYSDATE + ROWNUM dt, RPAD('x', 100, 'x') DATA
3 FROM dual CONNECT BY LEVEL <= 1E5);
Table created
SQL> CREATE INDEX test_idx ON TEST(dt);
Index created
SQL> EXPLAIN PLAN FOR
2 SELECT *
3 FROM (SELECT *
4 FROM TEST
5 WHERE dt IS NOT NULL
6 ORDER BY dt DESC)
7 WHERE ROWNUM <= 100;
Explained
SQL> SELECT * FROM table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 3326882503
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 100 | 6100 | 4 (0)|
|* 1 | COUNT STOPKEY | | | | |
| 2 | VIEW | | 93692 | 5581K| 4 (0)|
| 3 | TABLE ACCESS BY INDEX ROWID| TEST | 93692 | 5581K| 4 (0)|
|* 4 | INDEX FULL SCAN DESCENDING| TEST_IDX | 100 | | 2 (0)|
--------------------------------------------------------------------------------
此访问路径提供您正在查找的算法:向前或向后读取索引,直到返回所需的行数。
如果您没有获得此访问路径,可能是因为您正在搜索非索引值(NULLS),或者存在优化认为更有效的另一个访问路径。