我有这张桌子:
CREATE TABLE "TEST"."TEST_REQUESTS"
(
"REQUEST_ID" NUMBER(*,0) NOT NULL ENABLE,
"RECEPTION_TIME" TIMESTAMP (6) NOT NULL ENABLE,
"OPERATION" VARCHAR2(25 BYTE) NOT NULL ENABLE,
"XML_HEADER_IN" CLOB,
"XML_BODY_IN" CLOB NOT NULL ENABLE,
"STATUS_ID" NUMBER(*,0) NOT NULL ENABLE,
"CUSTOMER" VARCHAR2(25 BYTE)
)
它有2个索引:
CREATE INDEX "TEST"."TEST_REQUESTS_STATUS_IDX" ON "TEST"."TEST_REQUESTS"
(
"STATUS_ID" DESC
)
CREATE INDEX "TEST"."TEST_REQUESTS_TIME_IDX" ON "TEST"."TEST_REQUESTS"
(
"RECEPTION_TIME"
)
我也有一个或多或少的程序:
PROCEDURE TEST_LoadHistoryRequestRange (diasMantenidosIN IN number, [...] numRequestOut OUT number [...]) IS
tsStartLimit TIMESTAMP;
BEGIN
tsStartLimit := sysdate - diasMantenidosIN;
SELECT count(REQUEST_ID) into numRequestOut FROM TEST_REQUESTS WHERE STATUS_ID=0 and RECEPTION_TIME<tsStartLimit;
[...]
END;
现在这个表已经增长到接近1500万个寄存器......但是,花费近10分钟来制作那么简单COUNT
是合乎逻辑的吗?这可能有什么问题?
非常感谢!!
编辑:这是选择计数的解释计划:
Plan hash value: 378939817
----------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 14 | 4 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 14 | | |
|* 2 | TABLE ACCESS BY INDEX ROWID| TEST_REQUESTS | 1125 | 15750 | 4 (0)| 00:00:01 |
|* 3 | INDEX RANGE SCAN | TEST_REQUESTS_STATUS_IDX | 1 | | 3 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------------
答案 0 :(得分:2)
可能需要很长时间。查询的最佳索引是复合索引:
CREATE INDEX "TEST"."TEST_STATUS_REQUESTS_TIME_IDX" ON "TEST"."TEST_REQUESTS"
(
STATUS,
"RECEPTION_TIME",
REQUEST_ID
);
请注意,索引中列的顺序会有所不同。