Совокупная сумма производительности БД Oracle по сравнению с большим количеством кода

У меня есть таблица x с 53 столбцами и примерно 1 миллионом строк. Первый столбец — это идентификатор, а следующие 52 столбца — это денежные операции, которые происходят каждую неделю с определенной даты.

eg.

id,w1,w2,w3,w4,w5..w52
a1,0,5,1,4,0..43
a2,7,0,6,9,4..27

Мне нужна совокупная сумма транзакций за все эти недели на идентификатор. Одно из решений, которое я нашел, заключалось в том, чтобы использовать unpivot для получения 52 строк на идентификатор, а затем применять совокупную сумму.

sum(transaction) over (partition by id order by week asc)

Моя проблема здесь в том, что теперь у меня есть таблица с 60 миллионами строк, и Oracle работает очень медленно (запредельно так), сортируя получение суммы.

Другой вариант заключается в том, что я взял каждый столбец и вручную сложил их вместе следующим образом.

select 
 id,
 w1,
 w1+w2,
 w1+w2+w3,
 w1+w2+w3+w4,
 w1+w2+w3+w4+w5,
 ..
 w1+w2+w3+w4+w5..w49+w50+w51+w52

from x

Проблема здесь в том, что для получения простой формулы требуется много кода (написание его было мучением!).

Могу ли я в любом случае настроить свою таблицу (индекс/раздел), чтобы ускорить совокупную сумму по такому количеству строк, или любой код, который я могу использовать с моей исходной таблицей для достижения этих результатов с наименьшими усилиями?!


person user2207949    schedule 25.03.2013    source источник
comment
Проблема здесь в том, что это много кода (писать его было больно!). Почему это боль? напишите это один раз, сделайте из этого представление, и тогда вам не придется смотреть на это снова. Вы даже можете легко написать оператор SQL, чтобы сгенерировать этот SQL для вас как одноразовый.   -  person DazzaL    schedule 25.03.2013
comment
Настоящая проблема в том, что у вас плохо спроектированная модель данных. Вам было бы намного проще правильно нормировать таблицу.   -  person APC    schedule 25.03.2013
comment
@APC, возможно, так. Что бы вы предложили, чтобы структурировать данные, стоящие за этим? Мои исходные данные - это идентификатор, транзакция и дата. Транзакции происходят спорадически, но я отслеживаю производительность каждую неделю, и мне нужно увидеть недели, когда ничего не происходило и т. д.   -  person user2207949    schedule 26.03.2013


Ответы (1)


создайте представление, чтобы скрыть «много кода». например:

SQL> desc tester;
 Name                                      Null?    Type
 ----------------------------------------- -------- ---------------
 ID                                                 NUMBER
 W1                                                 NUMBER
 W2                                                 NUMBER
...
 W49                                                NUMBER
 W50                                                NUMBER
 W51                                                NUMBER
 W52                                                NUMBER

затем запустите SQL, например (в 11g вы можете использовать listagg вместо wm_concat для того же эффекта):

select 'create or replace view v_tester as select id ' from dual
union all
select * 
  from (select ','||replace(wm_concat(column_name) over (order by column_id), ',', '+') || ' as col' || rownum
  from user_tab_columns
 where table_name = 'TESTER'
   and column_id >= 2
 order by column_id)
union all
select ' from tester;' from dual;

для создания DDL, например:

create or replace view v_tester as select id 
,W1 as col1
,W1+W2 as col2
,W1+W2+W3 as col3
,W1+W2+W3+W4 as col4
,W1+W2+W3+W4+W5 as col5

и т. д., затем запустите это. теперь ваш код скрыт представлением и его относительно легко создавать.

person DazzaL    schedule 25.03.2013
comment
спасибо за предложение. Если я что-то не упустил, мне все равно нужно взять вывод этого кода и вставить его, а затем запустить, чтобы создать представление? - person user2207949; 26.03.2013
comment
@user2207949 user2207949 да (или используйте немедленное выполнение для него, чтобы создать его для вас), но это одноразовая вещь. - person DazzaL; 26.03.2013