Я воссоздал этот сценарий, как это ...
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 строк в данном случае)
проходит через первый выбирает все 657000 ...
select sum(paid_amt)
from test_table;
План ВЫБРАТЬ ЗАЯВЛЕНИЕ ALL_ROWSCost: 621 байт: 13 CARDINALITY: 1
2 SORT СОВОКУПНЫЕ Б 13 CARDINALITY : 1
1 ТАБЛИЦА ACCESS ПОЛНОЙ ТАБЛИЦА DAVE.TEST_TABLE Стоимость: 621 Bytes: 9923914 мощностные: 763.378
Тогда 109,650 за одну corpId ...
select sum(paid_amt)
from test_table
where corpId = 5;
план ЗЕЬЕСТА ALL_ROWSCost: 265 Б: 26 CARDINALITY: 1
3 SORT СОВОКУПНЫЕ Б: 26 CARDINALITY: 1
2 Таблицы ДОСТУП ROWID индексной Таблица DAVE.TEST_TABLE Стоимость: 265 Б: 3310138 Кардинальность: 127313
1 INDEX RANGE SCAN INDEX DAVE.TEST_TABLE_NUI_1 Стоимость: 213 Cardinality: 3054
И, наконец, 20836 строк ограничивающих по дате ...
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')
план ЗЕЬЕСТА ALL_ROWSCost: 265 Б: 35 CARDINALITY: 1
3 SORT СОВОКУПНЫЕ Б: 35 CARDINALITY: 1
2 Таблицы ДОСТУП ROWID индексной Таблица DAVE.TEST_TABLE Стоимость: 265 Б 871360 CARDINALITY : 24896
1 INDEX RANGE SCAN INDEX DAVE.TEST_TABLE_NUI_1 Стоимость: 213 Cardinality: 3,054
Все 3 запросы были быстрые (т.е. < 0,5 секунды)
Альтернативой было бы сбросить nui_1 и nui_2 и создать объединенный индекс для обоих столбцов. Это побежал в 31ms на моем дб
create index test_table_nui_3 on test_table(corpId, incoming_date);
План оператора SELECT ALL_ROWSCost: 15 Б: 35 мощностные: 1
3 SORT СОВОКУПНЫЕ Б: 35 мощностные: 1
2 ТАБЛИЦА ACCESS BY INDEX ROWID TABLE DAVE. test_table Стоимость: 15 Б: 871360 мощностные: 24896
1 INDEX RANGE SCAN INDEX DAVE.TEST_TABLE_NUI_3 Стоимость: 3 Cardinality: 14
Это говорит о том, что совокупная функция не проблема, но ваша индексация может быть. Лучше всего было бы проверить ваши планы объяснений.
Какие два запроса вы используете? В частности, когда вы не используете функцию aggregate, вы выбираете столбец 'paid_amt'? Каковы два плана запросов? Вы говорите, что для возврата последней из 64 000 строк требуется меньше секунды? Или вы используете графический интерфейс, который отображает первые несколько строк, прежде чем извлекать последнюю строку? –
2 запроса: первый из них я уже опубликовал, а второй - тот, который выбирает счетчик (используя count (*)). Счет дает 64k менее чем за секунду, а сумма занимает 4 минуты. – user2194253