我像这样重新创建了这个场景......
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_ROWS成本:621 字节:13 基数:1
2 SORT AGGREGATE 字节:13 基数:1
1 表访问全表 DAVE.TEST_TABLE 成本:621 字节:9,923,914 基数:763,378
然后 109,650 个 corpId...
select sum(paid_amt)
from test_table
where corpId = 5;
计划
SELECT STATEMENT ALL_ROWS成本:265 字节:26 基数:1
3 SORT AGGREGATE 字节:26 基数:1
2 按索引 ROWID 表访问表 DAVE.TEST_TABLE 成本:265 字节:3,310,138 基数:127,313
1 INDEX RANGE SCAN INDEX DAVE.TEST_TABLE_NUI_1 成本: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_ROWS成本:265 字节:35 基数:1
3 SORT AGGREGATE 字节:35 基数:1
2 按索引 ROWID 表访问表 DAVE.TEST_TABLE 成本:265 字节:871,360 基数:24,896
1 INDEX RANGE SCAN INDEX DAVE.TEST_TABLE_NUI_1 成本:213 基数:3,054
所有 3 个查询都很快速(即
另一种方法是删除 nui_1 和 nui_2 并在两列上创建组合索引。然后在我的数据库上运行了 31 毫秒
create index test_table_nui_3 on test_table(corpId, incoming_date);
计划
SELECT STATEMENT ALL_ROWSCost:15 字节:35 基数:1
3 SORT AGGREGATE 字节:35 基数:1
2 按索引 ROWID 表访问表 DAVE.TEST_TABLE 成本:15 字节:871,360 基数:24,896
1 INDEX RANGE SCAN INDEX DAVE.TEST_TABLE_NUI_3 成本:3 基数:14
这表明聚合函数不是问题,但您的索引可能是问题。最好的办法是检查您的解释计划。