我正在使用Oracle 11g。我有一张有45亿行的表。
Table Schema:
TableName: INFO
(
ID NUMBER NOT NULL , (Primary Key)
USER_NAME VARCHAR2(100 BYTE), (has less unique values)
DATED DATE, (has less unique values)
URI VARCHAR2(1000 BYTE),(Unique Key)
APPLICATION_TYPE VARCHAR2(100 BYTE), (has less unique values)
INFORMATION CLOB
)
并且还创建了一个索引:
create index check_index on INFO(dated desc, upper(uri), upper(user_name) asc);
现在查询是:
SELECT rnum,id,dated,URI,user_name,information,application_type FROM
( SELECT rownum rnum,id,dated,URI,user_name,information,application_type FROM
(select info.id,info.dated,info.URI,info.user_name,info.information,info.application_type from INFO
where LOWER(info.uri) like 'model://%' and
info.dated >= to_date('01-01-2014 00:00:00', 'DD-MM-YYYY hh24:mi:ss') and info.dated <= to_date('31-12-2014 23:59:59', 'DD-MM-YYYY hh24:mi:ss')
and info.user_name = 'whl' order by dated desc, upper(uri), upper(user_name) asc
) WHERE rownum <= 49000
)WHERE rnum >= 48900 ;
解释计划是:
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 3477643426
----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 49000 | 27M| 5 (0)| 00:00:01 |
|* 1 | VIEW | | 49000 | 27M| 5 (0)| 00:00:01 |
|* 2 | COUNT STOPKEY | | | | | |
| 3 | VIEW | | 49000 | 26M| 5 (0)| 00:00:01 |
|* 4 | TABLE ACCESS BY INDEX ROWID| AUDIT_INFO | 1025K| 301M| 5 (0)| 00:00:01 |
|* 5 | INDEX RANGE SCAN | CHECK_INDEX | 1 | | 4 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("RNUM">=48900)
2 - filter(ROWNUM<=49000)
4 - filter("INFO"."USER_NAME"='whl' AND LOWER("INFO"."URI") LIKE 'model://%')
5 - access(SYS_OP_DESCEND("DATED")>=HEXTORAW('878DF3E0E7C3C3FF') AND
SYS_OP_DESCEND("DATED")<=HEXTORAW('878DFEF8FEF8FEFAFF') )
filter(SYS_OP_UNDESCEND(SYS_OP_DESCEND("DATED"))>=TO_DATE(' 2014-01-01
00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND SYS_OP_UNDESCEND(SYS_OP_DESCEND("DATED"))<=TO
_DATE(' 2014-12-31 23:59:59', 'syyyy-mm-dd hh24:mi:ss'))
自动跟踪信息:
db block gets: 12
consistent gets: 2
physical reads: 0
redo size: 808
bytes sent via sql *net to client:580
And Explain Plan after increasing the value of rownum from 49000 to 60,000 and rnum from 48900 to 59900 is:
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 3477643426
----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 60000 | 33M| 5 (0)| 00:00:01 |
|* 1 | VIEW | | 60000 | 33M| 5 (0)| 00:00:01 |
|* 2 | COUNT STOPKEY | | | | | |
| 3 | VIEW | | 60000 | 32M| 5 (0)| 00:00:01 |
|* 4 | TABLE ACCESS BY INDEX ROWID| AUDIT_INFO | 1025K| 301M| 5 (0)| 00:00:01 |
|* 5 | INDEX RANGE SCAN | CHECK_INDEX | 1 | | 4 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("RNUM">=59900)
2 - filter(ROWNUM<=60000)
4 - filter("INFO"."USER_NAME"='whl' AND LOWER("INFO"."URI") LIKE 'model://%')
5 - access(SYS_OP_DESCEND("DATED")>=HEXTORAW('878DF3E0E7C3C3FF') AND
SYS_OP_DESCEND("DATED")<=HEXTORAW('878DFEF8FEF8FEFAFF') )
filter(SYS_OP_UNDESCEND(SYS_OP_DESCEND("DATED"))>=TO_DATE(' 2014-01-01
00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND SYS_OP_UNDESCEND(SYS_OP_DESCEND("DATED"))<=TO
_DATE(' 2014-12-31 23:59:59', 'syyyy-mm-dd hh24:mi:ss')) auto trace info:
db block gets: 6
consistent gets: 1
physical reads: 0
redo size: 860
bytes sent via sql *net to client: 582
如果我执行此查询,它将在0.865秒内返回100行。 现在的问题是,如果我将rownum的值从49000增加到51000或更高,并且rnum的值对应于rownum则需要花费很多时间,大约64秒或更长。
如果我从查询中删除rownum和rnum,那么所有查询都会在0.894秒内执行
所以我想知道什么是主要问题或任何花费时间的东西,我怎么能解决这个问题,无论如何要花费时间在几毫秒或大约1~2秒。 感谢