我像这样重新创建了这个场景......
CREATE TABLE test_table
( id integer
, corpId integer
, paid_amt number(10,2)
, incoming_date DATE );
ALTER TABLE test_table
add CONSTRAINT test_table_pk PRIMARY KEY (id);
create index test_table_nui_1 on test_table(corpId);
create index test_table_nui_2 on test_table(incoming_date);
create sequence test_table_seq;
insert into test_table
select test_table_seq.nextval
,MOD(test_table_seq.currval,6)
,MOD(test_table_seq.currval,10) + 1
,sysdate - MOD(test_table_seq.currval,200)
from all_objects, user_objects;
all_objects 和 user_objects 之间的笛卡尔连接只是一种快速插入大量记录的技巧。(在这种情况下为 657,000 行)
首先通过选择所有 657,000...
select sum(paid_amt)
from test_table;
计划 SELECT STATEMENT ALL_ROWSCost:621 字节:13 基数:1
2 SORT AGGREGATE 字节:13 基数:1
1 TABLE ACCESS FULL TABLE DAVE.TEST_TABLE 成本:621 字节:9,923,914 基数:763,378
然后一个corpId 109,650 ...
select sum(paid_amt)
from test_table
where corpId = 5;
计划 SELECT STATEMENT ALL_ROWSCost:265 字节:26 基数:1
3 SORT AGGREGATE 字节:26 基数:1
2 TABLE ACCESS BY INDEX ROWID TABLE DAVE.TEST_TABLE 成本:265 字节:3,310,138 基数:127,313
1 INDEX RANGE SCAN INDEX_NEX DAVE.TABLE 213 基数:3,054
最后是按日期限制的 20,836 行...
SELECT sum(paid_amt) totalamount
FROM test_table e
WHERE e.corpId = 5
AND e. incoming_date >= to_date('01-12-2012','dd-mm-yyyy')
AND e. incoming_date <= to_date('09-01-2013','dd-mm-yyyy')
计划 SELECT STATEMENT ALL_ROWSCost: 265 Bytes: 35 Cardinality: 1
3 SORT AGGREGATE Bytes: 35 Cardinality: 1
2 TABLE ACCESS BY INDEX ROWID TABLE DAVE.TEST_TABLE Cost: 265 Bytes: 871,360 Cardinality: 24,896
1 INDEX RANGE SCAN INDEX DAVE.TEST_TABLE 213 基数:3,054
所有 3 个查询都很快速(即 < 0.5 秒)
另一种方法是删除 nui_1 和 nui_2 并在两列上创建组合索引。然后在我的数据库上运行了 31 毫秒
create index test_table_nui_3 on test_table(corpId, incoming_date);
Plan SELECT STATEMENT ALL_ROWSCost: 15 Bytes: 35 Cardinality: 1
3 SORT AGGREGATE Bytes: 35 Cardinality: 1
2 TABLE ACCESS BY INDEX ROWID TABLE DAVE.TEST_TABLE 成本: 15 Bytes: 871,360 Cardinality: 24,896
1 INDEX RANGE SCAN INDEX_3 Cost: DAVE.TEST_TABLE_N 3 基数:14
这表明聚合函数不是问题,但您的索引可能是问题。最好的办法是检查你的解释计划。