Comments 136
Добрый день. Тема поднята хорошая. Есть ряд правильных моментов, но есть что добавить. Мне приходилось задаться вопросом потокового сохранения данных с датчиков. Ряд мест где вы, на мой взгляд, не правы или имеете ещё возможности к ускорению.
1) Redo в случае с temporary таблицами тоже пишется, увы. Хоть и меньше. Но это мелочи.
2) Чтобы уменьшить количество soft-parse, можно воспользоваться dbms_sql, создать единождый курсор, отпарсить его текст, а он у вас один и тот же всегда: (insert into ...). И просто подменяя значения bind переменных execute его с новыми значениями. Тем самым вы избавитесь даже от soft parse, которые хоть и легче, но всё равно ресурсоёмкие.
3) Constraints очень любят ресурсы. FK, PK, check (not null), unique — всё это ресурсы, которые тратит оракл при вышей вставке. Подумайте, если вы так гонитесь за скоростью, уверены ли вы, что вам нужно каждый раз проверять, что то что вы вставляете — соответсвует условиям constraints. Думаю ваш java код не настолько сложен и источник данных проверен и единообразен, потому можно было бы рискнуть не делать проверки при вставке (можно на крайняк сделать job, который раз в некоторое время находит «битые» данные в системе. Но констрейнты либо убрать вообще, либо оставить в декларативных целях, но воспользоваться RELY DESABLE NOVALIDATE;
4) BULK INSERT мне нравится (по сути это аналог FORALL в PL/SQL). Но если вы захотите воспользоваться вторым моим советом, то у вас возникнет вопрос, как же — частый вызов процедур из джавы в оракл — тоже ресурсоёмко и вы будете правы. Потому рекомендовал бы формировать буфер на джаве, а потом передавать в процедуру массивом сразу некоторое кол-во данных (параметр объявите как PL/SQL table). Ну и внутри PL/SQL процедуры уже bulk набор данных через уже отпарсеный запрос.
5) настройте параметры физического хранения таблицы PCTFREE/PCTUSED. PCTFREE можно поставить близким к 0. Т.к. предполагаю, что в этой таблице вам не нужны updates. Соответсвенно можно забивать датаблок «до краю». Реже выделяете новый датаблок — быстрее работаем.
6) Как у вас managed tablespace? (dictionary vs locally) Наверное уже в 2013 году вопрос не актуальный, но всё же…
7) Индексы!!! быстрый интенсивный DML и индексы — это два врага. Подумайте, так ли вам нужны индексы на этих таблицах. Тема отдельная, но если можете — лучше убейте их. Не думаю, что в контексте ваших датчиков вы будете искать строки по уникальному индексу, наверняка у вас какая-то batch обработка данных… В общем смотрите, где вы готовы потерять — при вставке почти удвоить время вставки из-за индекса или при вычитывании замедлится (ещё вопрос замедлится ли!!) из-за отсутсвия индексов!
8) Если не критично потеря небольшого кол-ва недописанных данных в случае падения инстанса (думаю вам подойдёт) почитайте про опции COMMIT NOWAIT BATCH (NOWAIT и BATCH это две раздельных фичи — почитайте).
9) По дополнительной настройке инстанса я особо не подскажу — тут DBA нужно чтобы подключились, там ещё немного можно было бы выжать (или убедится что мы не теряем на так называемой «контрольной точке» — убедитесь в достаточности размеров online redo logs итд).
Думаю если вы примените всё что я упомянул выше, вы выйдете на ещё более высокие просторы производительности в вашей системе.
Желаю удачи (если всё же попробуете применить — поделитесь результатами, пожалуйста, хотя бы в кратце — сколько в контексте ваших цифр показал прирост).
PS: Это то, что в голову пришло сразу. Может ещё чего придумаю. :)
1) Redo в случае с temporary таблицами тоже пишется, увы. Хоть и меньше. Но это мелочи.
2) Чтобы уменьшить количество soft-parse, можно воспользоваться dbms_sql, создать единождый курсор, отпарсить его текст, а он у вас один и тот же всегда: (insert into ...). И просто подменяя значения bind переменных execute его с новыми значениями. Тем самым вы избавитесь даже от soft parse, которые хоть и легче, но всё равно ресурсоёмкие.
3) Constraints очень любят ресурсы. FK, PK, check (not null), unique — всё это ресурсы, которые тратит оракл при вышей вставке. Подумайте, если вы так гонитесь за скоростью, уверены ли вы, что вам нужно каждый раз проверять, что то что вы вставляете — соответсвует условиям constraints. Думаю ваш java код не настолько сложен и источник данных проверен и единообразен, потому можно было бы рискнуть не делать проверки при вставке (можно на крайняк сделать job, который раз в некоторое время находит «битые» данные в системе. Но констрейнты либо убрать вообще, либо оставить в декларативных целях, но воспользоваться RELY DESABLE NOVALIDATE;
4) BULK INSERT мне нравится (по сути это аналог FORALL в PL/SQL). Но если вы захотите воспользоваться вторым моим советом, то у вас возникнет вопрос, как же — частый вызов процедур из джавы в оракл — тоже ресурсоёмко и вы будете правы. Потому рекомендовал бы формировать буфер на джаве, а потом передавать в процедуру массивом сразу некоторое кол-во данных (параметр объявите как PL/SQL table). Ну и внутри PL/SQL процедуры уже bulk набор данных через уже отпарсеный запрос.
5) настройте параметры физического хранения таблицы PCTFREE/PCTUSED. PCTFREE можно поставить близким к 0. Т.к. предполагаю, что в этой таблице вам не нужны updates. Соответсвенно можно забивать датаблок «до краю». Реже выделяете новый датаблок — быстрее работаем.
6) Как у вас managed tablespace? (dictionary vs locally) Наверное уже в 2013 году вопрос не актуальный, но всё же…
7) Индексы!!! быстрый интенсивный DML и индексы — это два врага. Подумайте, так ли вам нужны индексы на этих таблицах. Тема отдельная, но если можете — лучше убейте их. Не думаю, что в контексте ваших датчиков вы будете искать строки по уникальному индексу, наверняка у вас какая-то batch обработка данных… В общем смотрите, где вы готовы потерять — при вставке почти удвоить время вставки из-за индекса или при вычитывании замедлится (ещё вопрос замедлится ли!!) из-за отсутсвия индексов!
8) Если не критично потеря небольшого кол-ва недописанных данных в случае падения инстанса (думаю вам подойдёт) почитайте про опции COMMIT NOWAIT BATCH (NOWAIT и BATCH это две раздельных фичи — почитайте).
9) По дополнительной настройке инстанса я особо не подскажу — тут DBA нужно чтобы подключились, там ещё немного можно было бы выжать (или убедится что мы не теряем на так называемой «контрольной точке» — убедитесь в достаточности размеров online redo logs итд).
Думаю если вы примените всё что я упомянул выше, вы выйдете на ещё более высокие просторы производительности в вашей системе.
Желаю удачи (если всё же попробуете применить — поделитесь результатами, пожалуйста, хотя бы в кратце — сколько в контексте ваших цифр показал прирост).
PS: Это то, что в голову пришло сразу. Может ещё чего придумаю. :)
+11
PS: Ещё по ускорению savedata процедуры:
— Можно воспользоваться /*+ append */ и nologging
— Можно у seqence поднять значение cache (хотя в случае не-RAC системы это поможет в меньшей мере)
— Зачем в savedata Join-ится ряд таблиц я так и не понял, если честно. join-ится практически вся схема, а используются только данные из таблиц с алиасами A и E. То ли я что-то пропустил, то ли вы теряете время на этом.
— В идеале вообще избавится на этом этапе от join-ов и заливать данные как есть. На join-ах теряете время.
— первый и второй insert отличаются двумя условиями. Думаю что можно было бы переписать через insert into ALL WHEN — тоже вероятно ускорило бы.
— Можно воспользоваться /*+ append */ и nologging
— Можно у seqence поднять значение cache (хотя в случае не-RAC системы это поможет в меньшей мере)
— Зачем в savedata Join-ится ряд таблиц я так и не понял, если честно. join-ится практически вся схема, а используются только данные из таблиц с алиасами A и E. То ли я что-то пропустил, то ли вы теряете время на этом.
— В идеале вообще избавится на этом этапе от join-ов и заливать данные как есть. На join-ах теряете время.
— первый и второй insert отличаются двумя условиями. Думаю что можно было бы переписать через insert into ALL WHEN — тоже вероятно ускорило бы.
+4
1) Скорее всего будут проигнорированы на вставке во временные таблицы, но надо проверять, конечно
3) В тех-же целях что и FK, чтобы отсекать мусор в данных (в крайнем случае, этот балласт можно сбросить)
4) Такое решение возможно, но в моем случае, потребует хранить в памяти миллионы state-ов (правильнее в таком случае будет сразу использовать InMemory)
5) Да можно, это очень полезный совет
3) В тех-же целях что и FK, чтобы отсекать мусор в данных (в крайнем случае, этот балласт можно сбросить)
4) Такое решение возможно, но в моем случае, потребует хранить в памяти миллионы state-ов (правильнее в таком случае будет сразу использовать InMemory)
5) Да можно, это очень полезный совет
+1
1) Я говорю про вставку из временной таблицы в целевую таблицу — сделать там /*+ append*/
Кстати, при использовании процедуры, которая бы на месте вставляла бы сразу в целевую таблицу, пришедшие через параметр PL/SQL table данные, то гоняние данных из пустого в порожнее (использование temp table) можно было бы вообще избежать. минус undo/redo/temp, лишнее вычитывание — это всё время, снова таки.
3) Стоп-стоп-стоп, какие миллионы стейтов?
Вы вставляете данные из таблицы A (test_data) и E (test_state):
Зачем вы сюда join-ине таблицы b, c и d если вы их потом нигде не используете? Пустая трата ресурсов, если это не способ отфильтровать входящие данные по параметру uptime? Но и в этом случае, думаю, этот запрос можно было бы написать сильно оптимальнее, особенно учитывая что вы боретесь за доли секунды.
И, снова таки, не надо было его пускать в один поток с критической по производительности вставкой (я вообще всё ещё за выпиливание этой temp таблицы здесь. Не нужна она. Под слоганом, что temp table якобы не пишет undo/redo её сюда втулили ни к селу ни к городу. Субъективно. Пишите сразу в целевую таблицу. Хотите чтобы писалось по минимуму журналирования — покурите nologging и direct path write… впрочем при наличии индексов и внешних ключей ( не дай бог ещё и триггеров), direct path write Вам, увы, не светит).
Кстати, при использовании процедуры, которая бы на месте вставляла бы сразу в целевую таблицу, пришедшие через параметр PL/SQL table данные, то гоняние данных из пустого в порожнее (использование temp table) можно было бы вообще избежать. минус undo/redo/temp, лишнее вычитывание — это всё время, снова таки.
3) Стоп-стоп-стоп, какие миллионы стейтов?
Вы вставляете данные из таблицы A (test_data) и E (test_state):
insert into test_history(id, device_id, parameter_id, value, event_date)
select test_history_seq.nextval, a.device_id, a.parameter_id, e.value, e.last_date
from test_data a
inner join test_device b on ( b.id = a.device_id )
inner join test_parameter c on ( c.id = a.parameter_id )
inner join test_parameter_type d on ( d.id = c.type_id and d.name = 'uptime' )
left join test_state e on ( e.device_id = a.device_id and
e.parameter_id = a.parameter_id )
where e.value > a.value;
Зачем вы сюда join-ине таблицы b, c и d если вы их потом нигде не используете? Пустая трата ресурсов, если это не способ отфильтровать входящие данные по параметру uptime? Но и в этом случае, думаю, этот запрос можно было бы написать сильно оптимальнее, особенно учитывая что вы боретесь за доли секунды.
И, снова таки, не надо было его пускать в один поток с критической по производительности вставкой (я вообще всё ещё за выпиливание этой temp таблицы здесь. Не нужна она. Под слоганом, что temp table якобы не пишет undo/redo её сюда втулили ни к селу ни к городу. Субъективно. Пишите сразу в целевую таблицу. Хотите чтобы писалось по минимуму журналирования — покурите nologging и direct path write… впрочем при наличии индексов и внешних ключей ( не дай бог ещё и триггеров), direct path write Вам, увы, не светит).
+1
1) Надо попробовать, но не уверен, что будет работать
3) В статье device-ы в Java-коде генерируются с нуля, а в таблице лежат с 1-цы, этот мусор либо отсеивается join-ом, либо валит весь запрос на FK (я пока не уверен, возможно FK и лишние проверки придется отключить), про temp возможно что действительно субъективно, надо смотреть и другие варианты
3) В статье device-ы в Java-коде генерируются с нуля, а в таблице лежат с 1-цы, этот мусор либо отсеивается join-ом, либо валит весь запрос на FK (я пока не уверен, возможно FK и лишние проверки придется отключить), про temp возможно что действительно субъективно, надо смотреть и другие варианты
+1
1) ну смотря что и как сделаете. Если не выполните все условия, то, конечно, работать не будет. Список необходимых требований там всё таки действительно имеется.
3.1) Хм так может не генерируйте лишнее чтобы потом его не фильтровать? Зачем сначала записывать, чтобы потом фильтровать это? Снова таки — потери по той же производительности в самом факте лишней записи + в дорогих джойнах
3.2) Про Temp — просто моя субъективность основывается на многих годах разработки разных систем на БД, включая ETL-подобные. А в данном случае ещё и просто здравым смыслом, который говорит что вы делаете лишний шаг, который не добавляет никакой пользы. Только теряете на лишнюю запись в temp, а потом чтение из него. Из статьи так и не понятно зачем вы притулили temp таблицу. То что она расходует меньше ресурсов, ещё не повод её использовать. Ведь от того, что LOB эффективнее чем RAW вы не стали использовать ни один из этих типов, правда? Зачем же вы применили temp таблицу? Даже если вы хотите всё-же соединять ваш набор данных с другими таблицами (что при хорошей архитектуре системы тоже будет излишне, уверен), то можно всё равно сразу запустить вошедшую PL/SQL table вместо этой temp таблицы, и в SQL привести его к таблице и с ним работать напрямую.
В любом случае только лишний набор записей / чтения.
3.1) Хм так может не генерируйте лишнее чтобы потом его не фильтровать? Зачем сначала записывать, чтобы потом фильтровать это? Снова таки — потери по той же производительности в самом факте лишней записи + в дорогих джойнах
3.2) Про Temp — просто моя субъективность основывается на многих годах разработки разных систем на БД, включая ETL-подобные. А в данном случае ещё и просто здравым смыслом, который говорит что вы делаете лишний шаг, который не добавляет никакой пользы. Только теряете на лишнюю запись в temp, а потом чтение из него. Из статьи так и не понятно зачем вы притулили temp таблицу. То что она расходует меньше ресурсов, ещё не повод её использовать. Ведь от того, что LOB эффективнее чем RAW вы не стали использовать ни один из этих типов, правда? Зачем же вы применили temp таблицу? Даже если вы хотите всё-же соединять ваш набор данных с другими таблицами (что при хорошей архитектуре системы тоже будет излишне, уверен), то можно всё равно сразу запустить вошедшую PL/SQL table вместо этой temp таблицы, и в SQL привести его к таблице и с ним работать напрямую.
В любом случае только лишний набор записей / чтения.
+3
3.1) Чтобы не генерировать лишние записи в history, нужно знать значения state-ов (по нему и новым данным определяем пишем в history или нет). При этом сам state в БД обновляем всегда, так что данные в БД передавать все равно придется
3.2) Временные таблицы возникают из следующей цепочки рассуждений:
1. Надо использовать BULK для ускорения загрузки
2. BULK не работает для вызова хранимок
3. Недостаточно просто загрузить данные в history, данные обрабатываются при загрузке
4. Загружать временные данные в обычную таблицу накладно -> используем temporary
Наверняка задачу можно решить как-то еще (например передавая PL/SQL table и обрабатывая его процедурным кодом), но это надо пробовать
3.2) Временные таблицы возникают из следующей цепочки рассуждений:
1. Надо использовать BULK для ускорения загрузки
2. BULK не работает для вызова хранимок
3. Недостаточно просто загрузить данные в history, данные обрабатываются при загрузке
4. Загружать временные данные в обычную таблицу накладно -> используем temporary
Наверняка задачу можно решить как-то еще (например передавая PL/SQL table и обрабатывая его процедурным кодом), но это надо пробовать
+1
3.2.2 — ошибочное утверждение. Отсюда и весь сыр-бор.
Не надо в bulk вызывать хранимку. Надо в джаве сформировать массив с данными, которые вы хотите вставить и один раз вызвать хранимку, передав на вход массив. В хранимке в bulk-режиме вставить из этого массива в целевую таблицу.
Ваш PS правильный. Именно так и стоило бы сделать.
Не надо в bulk вызывать хранимку. Надо в джаве сформировать массив с данными, которые вы хотите вставить и один раз вызвать хранимку, передав на вход массив. В хранимке в bulk-режиме вставить из этого массива в целевую таблицу.
Ваш PS правильный. Именно так и стоило бы сделать.
+2
Не ошибочное. Скорее уводящее в другую сторону. Балкать процедуры действительно бессмысленно
+1
Ок, вопрос формулировки, суть это не отменяет, что из-за этого утверждения вы добавили ненужные затраты ресурсов в статье про улучшение производитлеьности вставки.
+1
Я описал один из возможных подходов. В рамках этого подхода — использование временных таблиц необходимо.
+1
ну, бесспорно, в рамках подхода использования temp таблиц — необходимо. Давайте ещё DBMS_LOB прикрутим — тоже в рамках подхода будет необходимо. А то что он тут не нужен — какая разница?
+2
Ну тут кое-кто external tables предлагает прикрутить, тоже неплохо
+1
external tables работают на механизме sqlldr. его вам уже предлагали. (вариант с exteranl tables на data pump не вспоминаю ибо вообще не в тему).
попробовать можете, конечно. Если добъетесь direct path write (снова уже обсуждали), то может и получите определённые преимущества… но есть и много недостатков.
1) вы говорили что вы планировали использовать одновременно несколько потоков для заливки. Это уже поставит под вопрос direct path write, и, в идеале, потребует некоторой переработки текущей архитектуры (на ваше усмотрение, конечно, но всё же).
2) sqlldr / ext table потребует предварительно выгрузить ваши данные в файл, а потом их загрузить — а это ещё один промежуточный буфер (причём на жёстком диске, а не в оперативке!!!), что явно не скажется положительно на производительности.
Исходя из этих размышлений я против sqlldr.
попробовать можете, конечно. Если добъетесь direct path write (снова уже обсуждали), то может и получите определённые преимущества… но есть и много недостатков.
1) вы говорили что вы планировали использовать одновременно несколько потоков для заливки. Это уже поставит под вопрос direct path write, и, в идеале, потребует некоторой переработки текущей архитектуры (на ваше усмотрение, конечно, но всё же).
2) sqlldr / ext table потребует предварительно выгрузить ваши данные в файл, а потом их загрузить — а это ещё один промежуточный буфер (причём на жёстком диске, а не в оперативке!!!), что явно не скажется положительно на производительности.
Исходя из этих размышлений я против sqlldr.
+1
PS: в качестве доказательств своих слов про Redo:
Обращаю внимание на redo size.
CREATE GLOBAL TEMPORARY TABLE tmp_1 (ID INTEGER) ON COMMIT PRESERVE ROWS;
set autotrace on
SQL> INSERT INTO tmp_1 SELECT ROWNUM FROM dba_objects;
90829 rows created.
Statistics
----------------------------------------------------------
838 recursive calls
1060 db block gets
3917 consistent gets
6 physical reads
255720 redo size
573 bytes sent via SQL*Net to client
527 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
59 sorts (memory)
0 sorts (disk)
90829 rows processed
Обращаю внимание на redo size.
+2
1) Знаю, но объем REDO на вставке во временные таблицы пренебрежимо мал (не стал писать чтобы не загромождать текст)
2) soft parse быть не должно, во всех примерах кроме первого, запрос разбирается один раз и потом используется в цикле.
3) Согласен, но FK я готов жертвовать только в самых крайних случаях (надо было померить конечно)
4) Согласен
5) Это безусловно
6) грешен
7) Тоже согласен, но по индексам надо смотреть, может какие-то будут нужны (в проекте логика обработки счетчиков более сложная чем я описал)
8) Знаю про эти фичи, думаю эффект будет на уровне примера с длинным commit-ом
9) Тоже согласен, там есть что покрутить
2) soft parse быть не должно, во всех примерах кроме первого, запрос разбирается один раз и потом используется в цикле.
3) Согласен, но FK я готов жертвовать только в самых крайних случаях (надо было померить конечно)
4) Согласен
5) Это безусловно
6) грешен
7) Тоже согласен, но по индексам надо смотреть, может какие-то будут нужны (в проекте логика обработки счетчиков более сложная чем я описал)
8) Знаю про эти фичи, думаю эффект будет на уровне примера с длинным commit-ом
9) Тоже согласен, там есть что покрутить
+1
1) «пренебрежимо мал», когда мы говорим про время на операцию, в среднем меньшее чем 1 десятитысячная секунды? Любопытно. См. выше — четверть мегабайта на 90000 записей с единственным integer полем. С такими пренебрежениями можно вообще об оптимизации не заботится.
2) На счёт soft parse, вы правы только отчасти. В рамках цикла, разбираться не будет. Цикл отрабатывает секунду. Потом начинается новая итерация (или ваши датчики работают только секунду?). На новой секунде вы получите новый prepareCall вызов и новый soft parse. Тобишь по разбору в секунду. А оно вам надо?
3) В этом я вас совсем не понимаю. просто ради интереса померяйте. Возможно сильно удивитесь сколько «едят» ваши констрейнты. Ещё раз — если очень беспокоитесь за то, что с датчика могли прийти данные, которые не ложатся на вашу схему данных — сделайте job, который будет проверять ваши данные и «вычищать» или помечать кривые данные. Можете пояснить зачем вам FK? Вы не уверены в тех данных, что вы вставляете или боитесь что прийдёт другой юзер и навставляет что-то кривое? Зачем на каждой вставке тратить ресурсы на валидацию?
6) Так о что грешен? Это был вопрос, как бы, а не утверждение, что у вас точно плохо всё. Я не знаю как у вас настроена база. Просто проверьте.
7) Неужели построчно выбираете данные, которые ломятся со скоростью порядка 8000 строк в секунду?
8) не совсем. Одно другому не мешает. Тем более что не вижу у вас в джаве распараллеливания потоков. Если бы у вас один поток вставлял данные bulk-ами, а другой собирал новый массив на вставку — это был бы один вопрос. А так, в вашем примере, выполнение последовательно. Соответсвенно формирование нового набора данных будет ожидать возвращения COMMIT-a. Конечно, сделав коммиты реже вы уменьшили влияние, но не отменили его совсем.
9)
2) На счёт soft parse, вы правы только отчасти. В рамках цикла, разбираться не будет. Цикл отрабатывает секунду. Потом начинается новая итерация (или ваши датчики работают только секунду?). На новой секунде вы получите новый prepareCall вызов и новый soft parse. Тобишь по разбору в секунду. А оно вам надо?
3) В этом я вас совсем не понимаю. просто ради интереса померяйте. Возможно сильно удивитесь сколько «едят» ваши констрейнты. Ещё раз — если очень беспокоитесь за то, что с датчика могли прийти данные, которые не ложатся на вашу схему данных — сделайте job, который будет проверять ваши данные и «вычищать» или помечать кривые данные. Можете пояснить зачем вам FK? Вы не уверены в тех данных, что вы вставляете или боитесь что прийдёт другой юзер и навставляет что-то кривое? Зачем на каждой вставке тратить ресурсы на валидацию?
6) Так о что грешен? Это был вопрос, как бы, а не утверждение, что у вас точно плохо всё. Я не знаю как у вас настроена база. Просто проверьте.
7) Неужели построчно выбираете данные, которые ломятся со скоростью порядка 8000 строк в секунду?
8) не совсем. Одно другому не мешает. Тем более что не вижу у вас в джаве распараллеливания потоков. Если бы у вас один поток вставлял данные bulk-ами, а другой собирал новый массив на вставку — это был бы один вопрос. А так, в вашем примере, выполнение последовательно. Соответсвенно формирование нового набора данных будет ожидать возвращения COMMIT-a. Конечно, сделав коммиты реже вы уменьшили влияние, но не отменили его совсем.
9)
+1
1) Да надо попробовать ваш вариант, без temp-ов, согласен
2) Ну это сильно упрощенный код, в продуктовом большинство запроса (а такие как здесь в первую очередь) парсятся один раз на сессию
3) Обязательно померю, возможно даже завтра
6) dictionary, пока все руки не дойдут это покрутить
7) Ну не все конечно, но некоторые возможно (пока еще к этому модулю не приступал, не могу сказать)
8) Ну в данном случае commit всего один, надо мерить с более короткими транзакциями
2) Ну это сильно упрощенный код, в продуктовом большинство запроса (а такие как здесь в первую очередь) парсятся один раз на сессию
3) Обязательно померю, возможно даже завтра
6) dictionary, пока все руки не дойдут это покрутить
7) Ну не все конечно, но некоторые возможно (пока еще к этому модулю не приступал, не могу сказать)
8) Ну в данном случае commit всего один, надо мерить с более короткими транзакциями
+1
1) PS: кстати, время на запись в сам temp tablespace всё-равно никуда не девается.
2) Ок. Тогда об этом стоило упомянуть в статье, если вы её посвящали инструментам оптимизации по вставке.
6) Тогда действительно «грешны» :)
7) в общем подумайте. index-ы это действительно дорого. На вашей структуре данных, если убрать констрейнты и индексы, я бы ожидал прирост производительности вставки в разы. Делаю ставки, на глаз, на приблизительно 5 раз при действительно массовой вставке (учитывая что у вас грубо 10000 строк в секунду, то только за день у вас около 800 млн строк… тут есть о чём задуматься).
Кстати, а таблицы секционированы? Индексы локальные или глобальные?
8) В данном — да. Но, я полагаю, мы рассматриваем некоторую систему, которая непрерывно получает данные с датчиков? Хотя, конечно, в статье об этом не сказано, но я как то на автомате применил свой опыт. Если мы снимаем 8000 значений, сохраняем их и забываем… то в общем то можно не сильно и беспокоится о производительности ) Просто в буфер всё сохранили, а потом неспешно записали.
2) Ок. Тогда об этом стоило упомянуть в статье, если вы её посвящали инструментам оптимизации по вставке.
6) Тогда действительно «грешны» :)
7) в общем подумайте. index-ы это действительно дорого. На вашей структуре данных, если убрать констрейнты и индексы, я бы ожидал прирост производительности вставки в разы. Делаю ставки, на глаз, на приблизительно 5 раз при действительно массовой вставке (учитывая что у вас грубо 10000 строк в секунду, то только за день у вас около 800 млн строк… тут есть о чём задуматься).
Кстати, а таблицы секционированы? Индексы локальные или глобальные?
8) В данном — да. Но, я полагаю, мы рассматриваем некоторую систему, которая непрерывно получает данные с датчиков? Хотя, конечно, в статье об этом не сказано, но я как то на автомате применил свой опыт. Если мы снимаем 8000 значений, сохраняем их и забываем… то в общем то можно не сильно и беспокоится о производительности ) Просто в буфер всё сохранили, а потом неспешно записали.
+1
А у меня тут возник вопрос — значение cache у sequence влияет как-то на результат в вашем случае? От дефлтного 20 до 1000 например?
+1
Если у Вас RAC — то очень влияют. В данном случае — слабо, но тоже влияют.
+2
Не обзательно RAC. Достаточно просто несколько параллельно вставляющих сессий в одном инстансе и seuqence c nocache, чтобы получить блокировки.
+1
Просто в RAC-е будет влиять на порядки больше, а в этом случае — на единицы процентов (один поток). При очень большом количестве потоков заливаемых данных, упомянутая система в целом вызывает целый ряд дополнительных вопросов, если честно, но они выходят за пределы этой статьи, я полагаю.
На счёт nocache — в исходнике у ТС nocache не упомянут, а по дефолту, кажется было cache 20 (могу сильно ошибаться).
На счёт nocache — в исходнике у ТС nocache не упомянут, а по дефолту, кажется было cache 20 (могу сильно ошибаться).
+1
Влияет в последних тестах, но незначительно, не стал расписывать. Вообще одна из редких опций которая часто полезна и очень редко вредит
0
Вредит она, если вам критична правильная последовательность событий в seq колонку и/или важно отсутсвие «дырок» в нумерации.
0
Да именно это я и имел в виду. На практике это часто необоснованная «хотелка»
0
Ну… если бы вы ваши же показания датчиков выстраивали в строгий хронологический ряд по этой колонке, думаю вы по-другому говорили бы. Ну и с других колоколень пример — бухгалтерский учёт, номера входящих / исходящих документов; номерация документов строгой отчётности итд итп :)
0
Если нужен хронологический ряд, поле типа DATE или TIMESTAMP гораздо надежнее. А делать что-то для бухгалтерского учета на seqeunce-ах… ну не стоит в общем, есть другие способы
0
Хм. Любопытно. Это какие другие более эффективные способы в например ERP-alike системе, вы предложите в многопользовательской системе, с конкурирующими 100+ пользователями. Действительно интересно. Если должна быть простая сквозная нумерация (кодирование через «личный номер пользователя»_«дата»_«номер док-та» и прочие подобные неприменимы).
0
Да, это безусловно головняк. Но просто взять и прикрутить sequence — не решение
0
Секвенцию использовать для непрерывной нумерации нельзя. Ибо нетранзакционна.
+1
Согласен, такая проблема есть. Но вероятность отката транзакции присваивания порядкового номера документа (по сути переведение состояния документа в нашем случае была настолько мизерна, что этим можно было пренебречь — хуже было от удалений документов. Приходилось добавлять механизм «сбора дырок» и потом повторного использования пропущенных номеров.
0
Ради интереса выполнил Ваш самый первый тест (который «не надо так делать») на СУБД Caché.
Результат — стабильно >4000 зап./с (i5-2400, 4Gb, ST3500413AS)
С оптимизацией выходит ещё быстрее.
На эту тему был топик «Выбор СУБД. Нужна очень быстрая вставка.» ( www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=759709&msg=8830867 ) и мне кажется, Вы там тоже участвовали.
Что касается [quote]Использование InMemory или NoSQL DB не изменит эту картину радикально.[/quote], то Caché очень даже радикально меняет картину: corp.cnews.ru/reviews/index.shtml?2011/08/24/452403_1
Результат — стабильно >4000 зап./с (i5-2400, 4Gb, ST3500413AS)
С оптимизацией выходит ещё быстрее.
На эту тему был топик «Выбор СУБД. Нужна очень быстрая вставка.» ( www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=759709&msg=8830867 ) и мне кажется, Вы там тоже участвовали.
Что касается [quote]Использование InMemory или NoSQL DB не изменит эту картину радикально.[/quote], то Caché очень даже радикально меняет картину: corp.cnews.ru/reviews/index.shtml?2011/08/24/452403_1
0
Ну… это уже зависит от того у кого какое железо. Может у человека на виртуалке сильно ограниченной всё это запускалось.
А делать так, всё-же, действительно не стоило, как он написал в разделе «не надо так делать». Ну, если производительность вставки действиетльно дорога. Особенно seqences на триггерах, hard-parses и пр. пр. пр. В общем начало темы правильное у него… только продолжать ещё можно много.
А делать так, всё-же, действительно не стоило, как он написал в разделе «не надо так делать». Ну, если производительность вставки действиетльно дорога. Особенно seqences на триггерах, hard-parses и пр. пр. пр. В общем начало темы правильное у него… только продолжать ещё можно много.
+1
Да, участвовал. Был молод и горяч
0
Что-то мне кажется, что самый быстрый способ был бы сделать текстовый файлик и грузить на сервере используя sqlldr :)
+2
Загрузить данные — полдела. Их надо еще обработать
0
А пробовали одновременно несколько процессов запустить? Какая получится максимальная суммарная производительность?
Надеюсь, что redo у вас достаточно размера, чтобы switch происходил не чаще раз в 10-15 минут.
Надеюсь, что redo у вас достаточно размера, чтобы switch происходил не чаще раз в 10-15 минут.
0
Нет не пробовал. По хорошему с разных хостов надо. REDO хватает
0
Можно и с одного пробовать, если все в количество IOPS на БД упирается.
Еще, как вариант, можно рассмотреть выкладывание текстовых файликов на сервер с БД и обработку их через external table.
Да, еще табличку test_state можно попробовать релизовать как материализованное представление с refresh on commit вместо использования merge.
Еще, как вариант, можно рассмотреть выкладывание текстовых файликов на сервер с БД и обработку их через external table.
Да, еще табличку test_state можно попробовать релизовать как материализованное представление с refresh on commit вместо использования merge.
0
Или вообще обычным view c использованием аналитических функий — при наличии на test_history индексов будет вполне шустро работать.
test_history секционируйте по event_date. От первичного ключа лучше вообще избавиться (убрать поле id). Или сделать его локальным, добавив event_date или приделать к id префикс на основе даты.
test_history секционируйте по event_date. От первичного ключа лучше вообще избавиться (убрать поле id). Или сделать его локальным, добавив event_date или приделать к id префикс на основе даты.
+1
Там к сожалению все не так просто. В state не обязательно последнее значение из history. Запись в history может вообще не формироваться для некоторых параметров (uptime например). State первично, не history. Если сохранять каждый снятый отсчет для uptime или счетчиков трафика, в history будет слишком много ненужного мусора
0
Как то слишком мало информации чтобы посоветовать что-то по сути.
0
Не хотел сильно загружать статью. В действительности схема данных выглядит так:
Страшная картинка
0
И почему я должен испугаться? :)
0
Ну я сам не из особо пугливых, но перспектива расписывать все это в статье меня не прельщает. За деревьями будет не видно леса.
0
Ок. Просто «лес» то тут то там всплывает как неописанные детали, которые влияют на ирхитектуру того, что написано в статье. Я даю комментарии исходи из того что читаю, и в этом контексте ещё много чего можно улучшить было. Может под вашу бизнес задачу и не подходит, но тогда не объективно ожидать, что ваши читатели знают Ваш контекст задачи.
0
Ну обработка — отдельная тема. Если хотите и есть вопросы, можем в Q&A обсудить проблемы, которые у вас с обработкой возникли. Но тут то мы обсуждали способы максимально быстрой заливки данных… а в этом контексте zhekappp прав — direct path load (write) самый быстрый метод. sqlldr — достаточно нелохой стандартный интерфейс для быстрой bulk-заливки данных.
0
direct path подходит только для однопоточной заливки.
Если есть возможность параллелить, то, возможно, если реализовать все вышеописанное (убрать все констраинты и индексы с таблички истории, убрать FK constraints с таблицы state, переделать с temp table на pl/sql table), то можно получить резальтаты даже лучше.
Если есть возможность параллелить, то, возможно, если реализовать все вышеописанное (убрать все констраинты и индексы с таблички истории, убрать FK constraints с таблицы state, переделать с temp table на pl/sql table), то можно получить резальтаты даже лучше.
0
100%
Либо через библиотеки, через тот же OCI можно заливать данные в режиме direct path write… но и в том и в другом случае от индексов и констрейнтов прийдётся отказаться :)
Либо через библиотеки, через тот же OCI можно заливать данные в режиме direct path write… но и в том и в другом случае от индексов и констрейнтов прийдётся отказаться :)
0
А bulk insert в обычную таблицу с триггером, какой результат выдает?
+1
Без последующей обработки — 10638 в секунду (против 30000 для временной таблицы). Помимо обработки, эти данные придется вычищать, на что также потребуется время
0
Обработку можно делать асинхронно вне зависимости от вставки данных.
Собсно мы всегда так и делали. Bulk insert + Асинхронный разгреб данных большими запросами.
Оно в итоге и стабильнее. Т.к. логика имеет свойства меняться и наворачиваться, а констрейнты мешаться )
В случае проблем, процесс наполнения не останавливается. Так и данные не теряются, и код простой.
Поэтому содержание статьи меня несколько удивило =)
Собсно мы всегда так и делали. Bulk insert + Асинхронный разгреб данных большими запросами.
Оно в итоге и стабильнее. Т.к. логика имеет свойства меняться и наворачиваться, а констрейнты мешаться )
В случае проблем, процесс наполнения не останавливается. Так и данные не теряются, и код простой.
Поэтому содержание статьи меня несколько удивило =)
+3
Подписуюсь и плюсую :)
0
Еще раз повторю 10 тыс. в секунду без commit-а. Так что данным никто не мешает потеряться.
0
Чем база данных отличается от просто текстового файла? По крайней мере тем, что она знает что-то о структуре и умеет оптимизировать работу с данными, в том числе с многими пользователями. Пока вы данные не загрузили, эти свойства базы данных не могут использоваться. Даже наоборот мешают, создают overhead. Поэтому грузить нужно глупым быстрым способом — sqlldr, а потом заставить базу собрать информацию о данных, чтобы она с ними дальше умно работала. Т.е. уже после загрузки всякие индексы, триггеры итд.
0
Ну, если Вы прочитали статью до конца, я приблизительно так и делаю. Использовать sqlloader для загрузки не очень удобно с технологической точки зрения.
0
Я дочитал. Хорошая теория — лучший практический инструмент. В общем, вы где-то велосипед изобретаете. Поэтому я вам рассказал об стандартном подходе и его обосновании. Тем более в телекомах и реляционных базах, конкретно оракл.
Обычно логи падают на диск в текстовом виде, им устраивается rotation, backup, archivation. В офлайне дергается скрипт с sqlldr, который время от времени грузит данные в базу. Таким образом даже наоборот решаются многие другие проблемы, например если база в оффлайне, или сеть упала, или данные кривые получились, итд. итп.
Обычно логи падают на диск в текстовом виде, им устраивается rotation, backup, archivation. В офлайне дергается скрипт с sqlldr, который время от времени грузит данные в базу. Таким образом даже наоборот решаются многие другие проблемы, например если база в оффлайне, или сеть упала, или данные кривые получились, итд. итп.
0
Как и обещал вчера, публикую краткий отчет по предложенным в обсуждении оптимизациям
Первым делом, естественно, вынес разбор запросов за пределы замеряемого временного интервала. Понятно, что при использовании временной таблицы (подход предложенный DenKrep пока не делал), измерения следует разбивать на две части:
1. Вставка во временную таблицу как была так и остается ~30000 записей в секунду для bulk_size = 100 (пару раз подскакивала до 60000)
2. Среднее время вызова хранимой процедуры замеряем (в миллисекундах с усреднением по 100 итерациям)
1. Исходный пример время вызова (~77 мс) делится на три части
1.1 Время выполнения каждого insert, в зависимости от количества добавляемых записей от 1 до 37 мс
1.2 Время выполнения merge ~32 мс
1.3 Остальное время commit ~10 мс
Очевидно, что чем меньше insert-ов тем лучше. Собственно insert all для объединения запросов не требуется, поскольку вставка идет в одну и ту-же таблицу.
2. Кеширование sequence влияет на insert-ы время выполнения меняется от 167 мс (nocache) до ~25 мс (начиная с cache 10 улучшение производительности в пределах погрешности измерений)
3. После того как убрал лишние Join-ы и отключил FK, время (без commit-а) ~48 мс
4. После последующего отключения индексов (без commit-а) ~40 мс
5. Замена commit на commit write nowait снижает время commit-а от 10 мс до ~0.
Первым делом, естественно, вынес разбор запросов за пределы замеряемого временного интервала. Понятно, что при использовании временной таблицы (подход предложенный DenKrep пока не делал), измерения следует разбивать на две части:
1. Вставка во временную таблицу как была так и остается ~30000 записей в секунду для bulk_size = 100 (пару раз подскакивала до 60000)
2. Среднее время вызова хранимой процедуры замеряем (в миллисекундах с усреднением по 100 итерациям)
1. Исходный пример время вызова (~77 мс) делится на три части
1.1 Время выполнения каждого insert, в зависимости от количества добавляемых записей от 1 до 37 мс
1.2 Время выполнения merge ~32 мс
1.3 Остальное время commit ~10 мс
Очевидно, что чем меньше insert-ов тем лучше. Собственно insert all для объединения запросов не требуется, поскольку вставка идет в одну и ту-же таблицу.
2. Кеширование sequence влияет на insert-ы время выполнения меняется от 167 мс (nocache) до ~25 мс (начиная с cache 10 улучшение производительности в пределах погрешности измерений)
3. После того как убрал лишние Join-ы и отключил FK, время (без commit-а) ~48 мс
4. После последующего отключения индексов (без commit-а) ~40 мс
5. Замена commit на commit write nowait снижает время commit-а от 10 мс до ~0.
0
PCTFREE 0 не оказало заметного влияния на производительность, но применять его на history безусловно нужно. Чтобы данные размещались более компактно
0
В пару PCTUSED 99 тоже можно попробовать поставить (хотя, вероятно не изменит картины).
А какие параметры физического хранения были до этого? Если таблица была не большая, может там initial покрывал наличие датаблоков, и до рекурсивных call-ов на выделение новых датаблоков не доходило?
А какие параметры физического хранения были до этого? Если таблица была не большая, может там initial покрывал наличие датаблоков, и до рекурсивных call-ов на выделение новых датаблоков не доходило?
0
Спасибо за статистику.
пара комментариев.
1. Видимо вы не поняли преимущества insert all. Даже в одну таблицу имеет смысл чтобы не выполнять повторно select которым формируется dataset.
4. Сколько строк при этом было в целевой таблице (читаем в индексе) b-level у индекса какой был? Надеюсь эксперимент проводили не с пустой таблицей?
пара комментариев.
1. Видимо вы не поняли преимущества insert all. Даже в одну таблицу имеет смысл чтобы не выполнять повторно select которым формируется dataset.
4. Сколько строк при этом было в целевой таблице (читаем в индексе) b-level у индекса какой был? Надеюсь эксперимент проводили не с пустой таблицей?
0
1. В данном случае select-ы очень похожи и легко сливаются в один. В иных случаях, преимущества insert all понятны
4. Не на пустой, но и на не очень большой (~10000 записей)
4. Не на пустой, но и на не очень большой (~10000 записей)
0
1. Хм, тогда не понимаю я, что вы имеете в виду под «select-ы сливаются в один», не используя insert all
4. На таком объёме это пока не так интересно, честно :) Самое забавное с Вашим потоком данных начнётся когда вы включите вашу машинку на полную мощность и погоняете хотя-бы 10-30 минут (а лучше 10 дней подряд). Надеюсь до того момента вам не надоест толпа комментирующих и вы поделитесь опытом. Поток то данных у вас достаточно любопытный, самом интересно было бы с таким «поигарться». У меня на опыте на порядок меньше в секунду. Правда и железо тогда было не в пример сегодняшнему…
4. На таком объёме это пока не так интересно, честно :) Самое забавное с Вашим потоком данных начнётся когда вы включите вашу машинку на полную мощность и погоняете хотя-бы 10-30 минут (а лучше 10 дней подряд). Надеюсь до того момента вам не надоест толпа комментирующих и вы поделитесь опытом. Поток то данных у вас достаточно любопытный, самом интересно было бы с таким «поигарться». У меня на опыте на порядок меньше в секунду. Правда и железо тогда было не в пример сегодняшнему…
0
1. Что то вроде:
2. К таким тестам я подойду не раньше чем через неделю (надо довольно много всего подготовить) Ну и не факт что я наберу такой поток на том что сейчас под рукой. Возможно придется генерить фейковые данные для тестирования производительности
insert into test_history(id, device_id, parameter_id, value, event_date)
select test_history_seq.nextval, a.device_id, a.parameter_id, a.value, a.event_date
from test_data a
inner join test_parameter c on ( c.id = a.parameter_id )
inner join test_parameter_type d on ( d.id = c.type_id)
left join test_state e on ( e.device_id = a.device_id and e.parameter_id = a.parameter_id )
where ((d.name = 'default' ) and (e.value is null or e.value <> a.value)) or
((d.name = 'uptime' ) and (e.value > a.value))
2. К таким тестам я подойду не раньше чем через неделю (надо довольно много всего подготовить) Ну и не факт что я наберу такой поток на том что сейчас под рукой. Возможно придется генерить фейковые данные для тестирования производительности
0
1. Понял, спасибо. Согласен, можно и так. Правда я OR конструкции очень не люблю. Надо на план получившегося смотреть. Как бы не получилось что оракл это всё равно превратил в union all. Но с insert all тоже может иногда быть не сахар. Надо сравнивать.
2. ок, в любом случае пишите, уже любопытно понаблюдать до чего это всё докатится.
2. ок, в любом случае пишите, уже любопытно понаблюдать до чего это всё докатится.
0
Когда дело дойдет до реальных тестов отпишу сюда и лично
+1
Спасибо
0
Померил на тесте максимально приближенном к реальному:
Здесь 5 последовательных замеров (количество вставок в секунду без учета времени обработки), в скобках среднее время обработки в мс.
plsql, commit, commit_nowait — Просто вызов в цикле обработчика для каждой записи (commit и commit_nowait с фиксацией изменений для каждого вызова)
collection — Передача массива, далее вызов в цикле обработчика одиночной записи с commit nowait в конце
temporary, distinct — Массовая вставка с использованием временной таблицы (различия в способе получения последнего значения счетчика: в первом случае — merge на вставке, во втором — вставляем все, группируем при обработке по индексу)
bulk — Передача массива, преобразование его в table, далее также как со временной таблицей (этот вариант максимально упрощен, делал только чтобы померить производительность)
В варианте temporary чертовски просто нарваться на ORA-600, при использовании bulk-запросов и наличии повторяющихся интерфейсов в одном bulk-е. По этой причине bulk=3, и производительность вставки такая низкая
plsql: 372, 376, 376, 374, 376
commit: 267, 259, 271, 261, 266
commit_nowait: 340, 338, 338, 336, 335
collection: 621, 441, 488, 789, 810
789, 809, 821, 810, 376
temporary: 2283, 1779, 1730, 1779, 2785 (93)
distinct: 2666, 2369, 2207, 2463, 2369 (109)
bulk: 1049, 1049, 1031, 1066, 1067
Здесь 5 последовательных замеров (количество вставок в секунду без учета времени обработки), в скобках среднее время обработки в мс.
plsql, commit, commit_nowait — Просто вызов в цикле обработчика для каждой записи (commit и commit_nowait с фиксацией изменений для каждого вызова)
collection — Передача массива, далее вызов в цикле обработчика одиночной записи с commit nowait в конце
temporary, distinct — Массовая вставка с использованием временной таблицы (различия в способе получения последнего значения счетчика: в первом случае — merge на вставке, во втором — вставляем все, группируем при обработке по индексу)
bulk — Передача массива, преобразование его в table, далее также как со временной таблицей (этот вариант максимально упрощен, делал только чтобы померить производительность)
Код пакета
create or replace type ae_state_rec as object (
device_id number,
profile_id number,
param_id number,
num varchar2(300),
value varchar2(300)
)
/
show errors;
create or replace type ae_state_tab as table of ae_state_rec;
/
show errors;
create or replace package ae_monitoring as
procedure addValue( p_device in number
, p_profile in number
, p_param in number
, p_num in varchar2
, p_val in varchar2 );
procedure addValues( p_tab in ae_state_tab );
procedure saveValues;
procedure saveValuesDistinct;
procedure saveValues( p_tab in ae_state_tab );
end ae_monitoring;
/
show errors;
create or replace package body ae_monitoring as
g_ifName_parameter constant number default 103;
g_default_policy constant number default 1;
g_uptime_policy constant number default 2;
g_threshold_policy constant number default 3;
g_increase_type constant number default 1;
g_decrease_type constant number default 2;
g_delta_type constant number default 3;
procedure addValue( p_device in number
, p_profile in number
, p_param in number
, p_num in varchar2
, p_val in varchar2 ) as
cursor c_res(p_type number) is
select r.id, r.name
from ae_resource r
where r.device_id = p_device
and r.res_num = p_num
and r.type_id = p_type
and r.start_date <= sysdate and sysdate <= nvl(r.end_date, sysdate + 1);
cursor c_state(p_resid number) is
select s.value
from ae_state s
where s.res_id = p_resid
and s.param_id = p_param;
l_resid ae_resource.id%type default null;
l_resname ae_resource.name%type default null;
l_oldval ae_state.value%type default null;
l_restype ae_profile_detail.type_id%type default null;
l_owntype ae_resource_type.owner_id%type default null;
l_owner ae_resource.id%type default null;
l_policy ae_state_policy.type_id%type default null;
l_polid ae_state_policy.id%type default null;
l_count number default 0;
begin
-- Получить тип ресурса
select d.type_id, r.owner_id
into l_restype, l_owntype
from ae_profile_detail d
inner join ae_resource_type r on (r.id = d.type_id)
where d.profile_id = p_profile
and d.param_id = p_param;
-- Получить ID владельца
if not l_owntype is null then
select r.id into l_owner
from ae_resource r
where r.device_id = p_device
and r.type_id = l_owntype;
end if;
-- Обработать имя интерфейса
if p_param = g_ifName_parameter then
open c_res(l_restype);
fetch c_res into l_resid, l_resname;
if c_res%notfound or l_resname <> p_val then
-- Закрыть старый ресурс интерфейса
update ae_resource set end_date = sysdate
where id = l_resid;
-- Создать новый ресурс интерфейса
insert into ae_resource(id, device_id, owner_id, type_id, res_num, name)
values (ae_resource_seq.nextval, p_device, l_owner, l_restype, p_num, p_val);
end if;
close c_res;
return;
end if;
-- Получить ID ресурса
open c_res(l_restype);
fetch c_res into l_resid, l_resname;
if c_res%notfound then
-- Если ресурс не найден, создать новый ресурс интерфейса
insert into ae_resource(id, device_id, owner_id, type_id, res_num, name)
values (ae_resource_seq.nextval, p_device, l_owner, l_restype, p_num, p_val)
returning id into l_resid;
end if;
-- Получить старое значение параметра
open c_state(l_resid);
fetch c_state into l_oldval;
if c_state%notfound then
l_oldval := null;
end if;
close c_state;
-- Получить политику сохранения значений
select l.type_id, l.id
into l_policy, l_polid
from ae_parameter p
inner join ae_domain d on (d.id = p.domain_id)
inner join ae_state_policy l on (l.id = d.policy_id)
where p.id = p_param;
-- Получить количество пересеченных порогов
select count(*)
into l_count
from ae_threshold t
where t.policy_id = l_polid
and (( t.type_id = g_increase_type and l_oldval <= t.value and p_val >= t.value ) or
( t.type_id = g_decrease_type and l_oldval >= t.value and p_val <= t.value ) or
( t.type_id = g_delta_type and abs(p_val - l_oldval) >= t.value ));
-- Сохранить запись в ae_state_log в соответствии с политикой
if l_oldval is null or l_count > 0 or
( l_policy = g_uptime_policy and p_val < l_oldval) or
( l_policy = g_default_policy and p_val <> l_oldval) then
insert into ae_state_log(id, res_id, param_id, value)
values (ae_state_log_seq.nextval, l_resid, p_param, decode(l_policy, g_uptime_policy, nvl(l_oldval, p_val), p_val));
end if;
-- Обновить ae_state
update ae_state set value = p_val
, datetime = current_timestamp
where res_id = l_resid and param_id = p_param;
if sql%rowcount = 0 then
insert into ae_state(id, param_id, res_id, value)
values (ae_state_seq.nextval, p_param, l_resid, p_val);
end if;
close c_res;
exception
when others then
if c_res%isopen then close c_res; end if;
if c_state%isopen then close c_state; end if;
raise;
end;
procedure addValues( p_tab in ae_state_tab ) as
begin
for i in 1 .. p_tab.count loop
addValue( p_device => p_tab(i).device_id
, p_profile => p_tab(i).profile_id
, p_param => p_tab(i).param_id
, p_num => p_tab(i).num
, p_val => p_tab(i).value );
end loop;
commit write nowait;
end;
procedure saveValues as
begin
-- Создать ресурс, если он отсутствует
merge into ae_resource d
using ( select t.id, t.device_id, t.num, t.value name, p.type_id, o.id owner_id
from ae_state_tmp t
inner join ae_profile_detail p on (p.profile_id = t.profile_id and p.param_id = t.param_id)
inner join ae_resource_type r on (r.id = p.type_id)
left join ae_resource o on (o.device_id = t.device_id and o.type_id = r.owner_id)
where t.param_id = g_ifName_parameter
) s
on ( d.device_id = s.device_id and d.res_num = s.num and d.type_id = s.type_id and
d.start_date <= sysdate and sysdate <= nvl(d.end_date, sysdate + 1) )
when matched then
update set d.tmp_id = s.id
where d.name <> s.name
when not matched then
insert (id, device_id, owner_id, type_id, res_num, name)
values (ae_resource_seq.nextval, s.device_id, s.owner_id, s.type_id, s.num, s.name);
-- Добавить недостающие ae_resource
insert into ae_resource(id, device_id, owner_id, type_id, res_num, name)
select ae_resource_seq.nextval, t.device_id, o.id, p.type_id, t.num, t.value
from ae_state_tmp t
inner join ae_resource c on (c.tmp_id = t.id)
inner join ae_profile_detail p on (p.profile_id = t.profile_id and p.param_id = t.param_id)
inner join ae_resource_type r on (r.id = p.type_id)
left join ae_resource o on (o.device_id = t.device_id and o.type_id = r.owner_id);
-- Закрыть устаревшие интерфейсы
update ae_resource set end_date = sysdate
, tmp_id = null
where tmp_id > 0;
-- Сохранить записи в ae_state_log
insert into ae_state_log(id, res_id, param_id, value)
select ae_state_log_seq.nextval, id, param_id, value
from ( select distinct r.id, t.param_id,
decode(l.type_id, g_uptime_policy, nvl(s.value, t.value), t.value) value
from ae_state_tmp t
inner join ae_profile_detail p on (p.profile_id = t.profile_id and p.param_id = t.param_id)
inner join ae_resource r on ( r.device_id = t.device_id and r.res_num = t.num and r.type_id = p.type_id and
r.start_date <= sysdate and sysdate <= nvl(r.end_date, sysdate + 1))
left join ae_state s on (s.res_id = r.id and s.param_id = t.param_id)
inner join ae_parameter a on (a.id = p.param_id)
inner join ae_domain d on (d.id = a.domain_id)
inner join ae_state_policy l on (l.id = d.policy_id)
left join ae_threshold h on (
h.policy_id = l.id and
(( h.type_id = g_increase_type and s.value <= h.value and t.value >= h.value ) or
( h.type_id = g_decrease_type and s.value >= h.value and t.value <= h.value ) or
( h.type_id = g_delta_type and abs(t.value - s.value) >= h.value )))
where ( s.id is null or not h.id is null
or ( l.type_id = g_uptime_policy and t.value < s.value )
or ( l.type_id = g_default_policy and t.value <> s.value ) )
and t.param_id <> g_ifName_parameter );
-- Обновить ae_state
merge into ae_state d
using ( select t.param_id, t.value, r.id res_id
from ae_state_tmp t
inner join ae_profile_detail p on (p.profile_id = t.profile_id and p.param_id = t.param_id)
inner join ae_resource r on ( r.device_id = t.device_id and r.res_num = t.num and r.type_id = p.type_id and
r.start_date <= sysdate and sysdate <= nvl(r.end_date, sysdate + 1))
where t.param_id <> g_ifName_parameter
) s
on (d.res_id = s.res_id and d.param_id = s.param_id)
when matched then
update set d.value = s.value
, d.datetime = current_timestamp
when not matched then
insert (id, param_id, res_id, value)
values (ae_state_seq.nextval, s.param_id, s.res_id, s.value);
-- Сохранить изменения
commit write nowait;
end;
procedure saveValuesDistinct as
begin
-- Создать ресурс, если он отсутствует
merge into ae_resource d
using ( select t.id, t.device_id, t.num, t.value name, p.type_id, o.id owner_id
from ( select device_id, profile_id, param_id, num
, max(id) keep (dense_rank last order by datetime) id
, max(value) keep (dense_rank last order by datetime) value
, max(datetime) datetime
from ae_state_tmp
group by device_id, profile_id, param_id, num
) t
inner join ae_profile_detail p on (p.profile_id = t.profile_id and p.param_id = t.param_id)
inner join ae_resource_type r on (r.id = p.type_id)
left join ae_resource o on (o.device_id = t.device_id and o.type_id = r.owner_id)
where t.param_id = g_ifName_parameter
) s
on ( d.device_id = s.device_id and d.res_num = s.num and d.type_id = s.type_id and
d.start_date <= sysdate and sysdate <= nvl(d.end_date, sysdate + 1) )
when matched then
update set d.tmp_id = s.id
where d.name <> s.name
when not matched then
insert (id, device_id, owner_id, type_id, res_num, name)
values (ae_resource_seq.nextval, s.device_id, s.owner_id, s.type_id, s.num, s.name);
-- Добавить недостающие ae_resource
insert into ae_resource(id, device_id, owner_id, type_id, res_num, name)
select ae_resource_seq.nextval, t.device_id, o.id, p.type_id, t.num, t.value
from ( select device_id, profile_id, param_id, num
, max(id) keep (dense_rank last order by datetime) id
, max(value) keep (dense_rank last order by datetime) value
, max(datetime) datetime
from ae_state_tmp
group by device_id, profile_id, param_id, num
) t
inner join ae_resource c on (c.tmp_id = t.id)
inner join ae_profile_detail p on (p.profile_id = t.profile_id and p.param_id = t.param_id)
inner join ae_resource_type r on (r.id = p.type_id)
left join ae_resource o on (o.device_id = t.device_id and o.type_id = r.owner_id);
-- Закрыть устаревшие интерфейсы
update ae_resource set end_date = sysdate
, tmp_id = null
where tmp_id > 0;
-- Сохранить записи в ae_state_log
insert into ae_state_log(id, res_id, param_id, value)
select ae_state_log_seq.nextval, id, param_id, value
from ( select distinct r.id, t.param_id,
decode(l.type_id, g_uptime_policy, nvl(s.value, t.value), t.value) value
from ( select device_id, profile_id, param_id, num
, max(id) keep (dense_rank last order by datetime) id
, max(value) keep (dense_rank last order by datetime) value
, max(datetime) datetime
from ae_state_tmp
group by device_id, profile_id, param_id, num
) t
inner join ae_profile_detail p on (p.profile_id = t.profile_id and p.param_id = t.param_id)
inner join ae_resource r on ( r.device_id = t.device_id and r.res_num = t.num and r.type_id = p.type_id and
r.start_date <= sysdate and sysdate <= nvl(r.end_date, sysdate + 1))
left join ae_state s on (s.res_id = r.id and s.param_id = t.param_id)
inner join ae_parameter a on (a.id = p.param_id)
inner join ae_domain d on (d.id = a.domain_id)
inner join ae_state_policy l on (l.id = d.policy_id)
left join ae_threshold h on (
h.policy_id = l.id and
(( h.type_id = g_increase_type and s.value <= h.value and t.value >= h.value ) or
( h.type_id = g_decrease_type and s.value >= h.value and t.value <= h.value ) or
( h.type_id = g_delta_type and abs(t.value - s.value) >= h.value )))
where ( s.id is null or not h.id is null
or ( l.type_id = g_uptime_policy and t.value < s.value )
or ( l.type_id = g_default_policy and t.value <> s.value ) )
and t.param_id <> g_ifName_parameter );
-- Обновить ae_state
merge into ae_state d
using ( select t.param_id, t.value, r.id res_id
from ( select device_id, profile_id, param_id, num
, max(id) keep (dense_rank last order by datetime) id
, max(value) keep (dense_rank last order by datetime) value
, max(datetime) datetime
from ae_state_tmp
group by device_id, profile_id, param_id, num
) t
inner join ae_profile_detail p on (p.profile_id = t.profile_id and p.param_id = t.param_id)
inner join ae_resource r on ( r.device_id = t.device_id and r.res_num = t.num and r.type_id = p.type_id and
r.start_date <= sysdate and sysdate <= nvl(r.end_date, sysdate + 1))
where t.param_id <> g_ifName_parameter
) s
on (d.res_id = s.res_id and d.param_id = s.param_id)
when matched then
update set d.value = s.value
, d.datetime = current_timestamp
when not matched then
insert (id, param_id, res_id, value)
values (ae_state_seq.nextval, s.param_id, s.res_id, s.value);
-- Сохранить изменения
commit write nowait;
end;
procedure saveValues( p_tab in ae_state_tab ) as
begin
-- Создать ресурс, если он отсутствует
merge into ae_resource d
using ( select t.device_id, t.num, t.value name, p.type_id, o.id owner_id
from ( select device_id, profile_id, param_id, num
, max(value) value
from table( p_tab )
group by device_id, profile_id, param_id, num
) t
inner join ae_profile_detail p on (p.profile_id = t.profile_id and p.param_id = t.param_id)
inner join ae_resource_type r on (r.id = p.type_id)
left join ae_resource o on (o.device_id = t.device_id and o.type_id = r.owner_id)
where t.param_id = g_ifName_parameter
) s
on ( d.device_id = s.device_id and d.res_num = s.num and d.type_id = s.type_id and
d.start_date <= sysdate and sysdate <= nvl(d.end_date, sysdate + 1) )
when not matched then
insert (id, device_id, owner_id, type_id, res_num, name)
values (ae_resource_seq.nextval, s.device_id, s.owner_id, s.type_id, s.num, s.name);
-- Сохранить записи в ae_state_log
insert into ae_state_log(id, res_id, param_id, value)
select ae_state_log_seq.nextval, id, param_id, value
from ( select distinct r.id, t.param_id,
decode(l.type_id, g_uptime_policy, nvl(s.value, t.value), t.value) value
from ( select device_id, profile_id, param_id, num
, max(value) value
from table( p_tab )
group by device_id, profile_id, param_id, num
) t
inner join ae_profile_detail p on (p.profile_id = t.profile_id and p.param_id = t.param_id)
inner join ae_resource r on ( r.device_id = t.device_id and r.res_num = t.num and r.type_id = p.type_id and
r.start_date <= sysdate and sysdate <= nvl(r.end_date, sysdate + 1))
left join ae_state s on (s.res_id = r.id and s.param_id = t.param_id)
inner join ae_parameter a on (a.id = p.param_id)
inner join ae_domain d on (d.id = a.domain_id)
inner join ae_state_policy l on (l.id = d.policy_id)
left join ae_threshold h on (
h.policy_id = l.id and
(( h.type_id = g_increase_type and s.value <= h.value and t.value >= h.value ) or
( h.type_id = g_decrease_type and s.value >= h.value and t.value <= h.value ) or
( h.type_id = g_delta_type and abs(t.value - s.value) >= h.value )))
where ( s.id is null or not h.id is null
or ( l.type_id = g_uptime_policy and t.value < s.value )
or ( l.type_id = g_default_policy and t.value <> s.value ) )
and t.param_id <> g_ifName_parameter );
-- Обновить ae_state
merge into ae_state d
using ( select t.param_id, t.value, r.id res_id
from ( select device_id, profile_id, param_id, num
, max(value) value
from table( p_tab )
group by device_id, profile_id, param_id, num
) t
inner join ae_profile_detail p on (p.profile_id = t.profile_id and p.param_id = t.param_id)
inner join ae_resource r on ( r.device_id = t.device_id and r.res_num = t.num and r.type_id = p.type_id and
r.start_date <= sysdate and sysdate <= nvl(r.end_date, sysdate + 1))
where t.param_id <> g_ifName_parameter
) s
on (d.res_id = s.res_id and d.param_id = s.param_id)
when matched then
update set d.value = s.value
, d.datetime = current_timestamp
when not matched then
insert (id, param_id, res_id, value)
values (ae_state_seq.nextval, s.param_id, s.res_id, s.value);
-- Сохранить изменения
commit write nowait;
end;
end ae_monitoring;
/
show errors;
Код теста
package com.amfitel.m2000.ae.tests.jdbc;
import oracle.jdbc.driver.OracleCallableStatement;
import oracle.sql.*;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class Test {
private final static String CLASS_NAME = "oracle.jdbc.driver.OracleDriver";
private final static String USER_CONN = "jdbc:oracle:thin:@192.168.124.35:1521:dev101";
private final static String USER_NAME = "ais";
private final static String USER_PASS = "ais";
private final static boolean AUTO_COMMIT_MODE = false;
private final static int BULK_SIZE = 1;
private final static int ALL_SIZE = 1000;
private final static String INS_VAL_SQL =
"insert into ae_state_tmp(id, device_id, profile_id, param_id, num, value) values (?,?,?,?,?,?)";
private final static String MERGE_VAL_SQL =
"merge into ae_state_tmp d " +
"using ( select ? id,? device_id,? profile_id,? param_id,? num,? value " +
" from dual" +
" ) s " +
"on ( d.device_id = s.device_id and d.profile_id = s.profile_id and " +
" d.param_id = s.param_id and d.num = s.num ) " +
"when matched then " +
" update set d.value = s.value " +
"when not matched then " +
" insert (id, device_id, profile_id, param_id, num, value) " +
" values (s.id, s.device_id, s.profile_id, s.param_id, s.num, s.value)";
private final static String SAVE_VALUES_SQL =
"begin ae_monitoring.saveValues; end;";
private final static String SAVE_VALUES_DISTINCT_SQL =
"begin ae_monitoring.saveValuesDistinct; end;";
private final static String ADD_VAL_SQL =
"begin ae_monitoring.addValue(?,?,?,?,?); end;";
private final static String ADD_VALUES_SQL =
"begin ae_monitoring.addValues(?); end;";
private final static String BULK_VALUES_SQL =
"begin ae_monitoring.saveValues(?); end;";
private final static Long DEVICE_ID = 0L;
private final static Long PROFILE_ID = 1L;
private final static Long UPTIME_PARAM_ID = 101L;
private final static Long IFNAME_PARAM_ID = 103L;
private final static Long INOCT_PARAM_ID = 104L;
private final static String FAKE_NUM_VALUE = "0";
private Connection c = null;
private void test_plsql() throws SQLException {
System.out.println("test_plsql:");
CallableStatement st = c.prepareCall(ADD_VAL_SQL);
Long timestamp = System.currentTimeMillis();
Long uptime = 0L;
Long inoct = 0L;
try {
for (int i = 1; i <= ALL_SIZE; i++) {
// Передать uptime
st.setLong(1, DEVICE_ID);
st.setLong(2, PROFILE_ID);
st.setLong(3, UPTIME_PARAM_ID);
st.setString(4, FAKE_NUM_VALUE);
st.setString(5, uptime.toString());
st.execute();
// Передать имя интерфейса
st.setLong(1, DEVICE_ID);
st.setLong(2, PROFILE_ID);
st.setLong(3, IFNAME_PARAM_ID);
st.setString(4, Integer.toString((i % 100) + 1));
st.setString(5, Integer.toString((i % 100) + 1));
st.execute();
// Передать счетчик трафика
st.setLong(1, DEVICE_ID);
st.setLong(2, PROFILE_ID);
st.setLong(3, INOCT_PARAM_ID);
st.setString(4, Integer.toString((i % 100) + 1));
st.setString(5, inoct.toString());
st.execute();
// Увеличить счетчики
uptime += 100L;
if (uptime >= 1000) {
uptime = 0L;
}
inoct += 10L;
}
} finally {
st.close();
}
Long delta_1 = System.currentTimeMillis() - timestamp;
System.out.println((ALL_SIZE * 1000L) / delta_1);
timestamp = System.currentTimeMillis();
c.commit();
Long delta_2 = System.currentTimeMillis() - timestamp;
System.out.println(delta_2);
System.out.println((ALL_SIZE * 1000L) / (delta_1 - delta_2));
}
private void test_temporary() throws SQLException {
System.out.println("test_temporary:");
CallableStatement st = c.prepareCall(MERGE_VAL_SQL);
Long timestamp = System.currentTimeMillis();
Long uptime = 0L;
Long inoct = 0L;
Long ix = 1L;
int bulk = 1;
try {
for (int i = 1; i <= ALL_SIZE; i++) {
// Передать uptime
st.setLong(1, ix++);
st.setLong(2, DEVICE_ID);
st.setLong(3, PROFILE_ID);
st.setLong(4, UPTIME_PARAM_ID);
st.setString(5, FAKE_NUM_VALUE);
st.setString(6, uptime.toString());
st.addBatch();
// Передать имя интерфейса
st.setLong(1, ix++);
st.setLong(2, DEVICE_ID);
st.setLong(3, PROFILE_ID);
st.setLong(4, IFNAME_PARAM_ID);
st.setString(5, Integer.toString((i % 100) + 1));
st.setString(6, Integer.toString((i % 100) + 1));
st.addBatch();
// Передать счетчик трафика
st.setLong(1, ix++);
st.setLong(2, DEVICE_ID);
st.setLong(3, PROFILE_ID);
st.setLong(4, INOCT_PARAM_ID);
st.setString(5, Integer.toString((i % 100) + 1));
st.setString(6, inoct.toString());
st.addBatch();
if (--bulk <= 0) {
st.executeBatch();
bulk = 1;
}
// Увеличить счетчики
uptime += 100L;
if (uptime >= 1000) {
uptime = 0L;
}
inoct += 10L;
}
if (bulk < 1) {
st.executeBatch();
}
} finally {
st.close();
}
Long delta_1 = System.currentTimeMillis() - timestamp;
System.out.println((ALL_SIZE * 1000L) / delta_1);
timestamp = System.currentTimeMillis();
st = c.prepareCall(SAVE_VALUES_SQL);
timestamp = System.currentTimeMillis();
try {
st.execute();
} finally {
st.close();
}
Long delta_2 = System.currentTimeMillis() - timestamp;
System.out.println(delta_2);
System.out.println((ALL_SIZE * 1000L) / (delta_1 - delta_2));
}
private void test_temporary_distinct() throws SQLException {
System.out.println("test_temporary:");
CallableStatement st = c.prepareCall(INS_VAL_SQL);
Long timestamp = System.currentTimeMillis();
Long uptime = 0L;
Long inoct = 0L;
Long ix = 1L;
int bulk = BULK_SIZE;
try {
for (int i = 1; i <= ALL_SIZE; i++) {
// Передать uptime
st.setLong(1, ix++);
st.setLong(2, DEVICE_ID);
st.setLong(3, PROFILE_ID);
st.setLong(4, UPTIME_PARAM_ID);
st.setString(5, FAKE_NUM_VALUE);
st.setString(6, uptime.toString());
st.addBatch();
// Передать имя интерфейса
st.setLong(1, ix++);
st.setLong(2, DEVICE_ID);
st.setLong(3, PROFILE_ID);
st.setLong(4, IFNAME_PARAM_ID);
st.setString(5, Integer.toString((i % 100) + 1));
st.setString(6, Integer.toString((i % 100) + 1));
st.addBatch();
// Передать счетчик трафика
st.setLong(1, ix++);
st.setLong(2, DEVICE_ID);
st.setLong(3, PROFILE_ID);
st.setLong(4, INOCT_PARAM_ID);
st.setString(5, Integer.toString((i % 100) + 1));
st.setString(6, inoct.toString());
st.addBatch();
if (--bulk <= 0) {
st.executeBatch();
bulk = BULK_SIZE;
}
// Увеличить счетчики
uptime += 100L;
if (uptime >= 1000) {
uptime = 0L;
}
inoct += 10L;
}
if (bulk < BULK_SIZE) {
st.executeBatch();
}
} finally {
st.close();
}
Long delta_1 = System.currentTimeMillis() - timestamp;
System.out.println((ALL_SIZE * 1000L) / delta_1);
timestamp = System.currentTimeMillis();
st = c.prepareCall(SAVE_VALUES_DISTINCT_SQL);
timestamp = System.currentTimeMillis();
try {
st.execute();
} finally {
st.close();
}
Long delta_2 = System.currentTimeMillis() - timestamp;
System.out.println(delta_2);
System.out.println((ALL_SIZE * 1000L) / (delta_1 - delta_2));
}
private void test_collection() throws SQLException {
System.out.println("test_collection:");
OracleCallableStatement st = (OracleCallableStatement)c.prepareCall(ADD_VALUES_SQL);
int oracleId = CharacterSet.CL8MSWIN1251_CHARSET;
CharacterSet charSet = CharacterSet.make(oracleId);
Long timestamp = System.currentTimeMillis();
Long uptime = 0L;
Long inoct = 0L;
RecType r[] = new RecType[ALL_SIZE * 3];
int ix = 0;
for (int i = 1; i <= ALL_SIZE; i++) {
// Передать uptime
r[ix++] = new RecType(
new NUMBER(DEVICE_ID),
new NUMBER(PROFILE_ID),
new NUMBER(UPTIME_PARAM_ID),
new CHAR(FAKE_NUM_VALUE, charSet),
new CHAR(uptime.toString(), charSet));
// Передать имя интерфейса
r[ix++] = new RecType(
new NUMBER(DEVICE_ID),
new NUMBER(PROFILE_ID),
new NUMBER(IFNAME_PARAM_ID),
new CHAR(Integer.toString((i % 100) + 1), charSet),
new CHAR(Integer.toString((i % 100) + 1), charSet));
// Передать счетчик трафика
r[ix++] = new RecType(
new NUMBER(DEVICE_ID),
new NUMBER(PROFILE_ID),
new NUMBER(INOCT_PARAM_ID),
new CHAR(Integer.toString((i % 100) + 1), charSet),
new CHAR(inoct.toString(), charSet));
// Увеличить счетчики
uptime += 100L;
if (uptime >= 1000) {
uptime = 0L;
}
inoct += 10L;
}
RecTab t = new RecTab(r);
try {
st.setORAData(1, t);
st.execute();
} finally {
st.close();
}
System.out.println((ALL_SIZE * 1000L) / (System.currentTimeMillis() - timestamp));
}
private void test_bulk() throws SQLException {
System.out.println("test_bulk:");
OracleCallableStatement st = (OracleCallableStatement)c.prepareCall(BULK_VALUES_SQL);
int oracleId = CharacterSet.CL8MSWIN1251_CHARSET;
CharacterSet charSet = CharacterSet.make(oracleId);
Long timestamp = System.currentTimeMillis();
Long uptime = 0L;
Long inoct = 0L;
RecType r[] = new RecType[ALL_SIZE * 3];
int ix = 0;
for (int i = 1; i <= ALL_SIZE; i++) {
// Передать uptime
r[ix++] = new RecType(
new NUMBER(DEVICE_ID),
new NUMBER(PROFILE_ID),
new NUMBER(UPTIME_PARAM_ID),
new CHAR(FAKE_NUM_VALUE, charSet),
new CHAR(uptime.toString(), charSet));
// Передать имя интерфейса
r[ix++] = new RecType(
new NUMBER(DEVICE_ID),
new NUMBER(PROFILE_ID),
new NUMBER(IFNAME_PARAM_ID),
new CHAR(Integer.toString((i % 100) + 1), charSet),
new CHAR(Integer.toString((i % 100) + 1), charSet));
// Передать счетчик трафика
r[ix++] = new RecType(
new NUMBER(DEVICE_ID),
new NUMBER(PROFILE_ID),
new NUMBER(INOCT_PARAM_ID),
new CHAR(Integer.toString((i % 100) + 1), charSet),
new CHAR(inoct.toString(), charSet));
// Увеличить счетчики
uptime += 100L;
if (uptime >= 1000) {
uptime = 0L;
}
inoct += 10L;
}
RecTab t = new RecTab(r);
try {
st.setORAData(1, t);
st.execute();
} finally {
st.close();
}
System.out.println((ALL_SIZE * 1000L) / (System.currentTimeMillis() - timestamp));
}
private void start() throws ClassNotFoundException, SQLException {
Class.forName(CLASS_NAME);
c = DriverManager.getConnection(USER_CONN, USER_NAME, USER_PASS);
c.setAutoCommit(AUTO_COMMIT_MODE);
}
private void stop() throws SQLException {
if (c != null) {
c.close();
}
}
public static void main(String[] args) {
Test t = new Test();
try {
try {
t.start();
t.test_plsql();
t.test_temporary();
t.test_temporary_distinct();
t.test_collection();
t.test_bulk();
} finally {
t.stop();
}
} catch (Exception e) {
System.out.println(e.toString());
}
}
}
В варианте temporary чертовски просто нарваться на ORA-600, при использовании bulk-запросов и наличии повторяющихся интерфейсов в одном bulk-е. По этой причине bulk=3, и производительность вставки такая низкая
0
Хм. Код стал уже действительно достаточно навороченный и проблемы с производительностью могут быть очень во многих местах.
Очень удивило что bulk работает в вашем случае в два раза медленнее чем temporary. Интересно было бы покопать почему…
Очень удивило что bulk работает в вашем случае в два раза медленнее чем temporary. Интересно было бы покопать почему…
0
А убрать PK, все индексы и FK с таблицы ae_state_log пробовали?
0
FK и прочих индексов там сейчас нет, PK не убирал
0
Если на эту табличку никто ссылаться не будет, то можно отойти от канонов и убрать PK и его индекс — практической пользы от него все равно никакой.
И еще не нравится троекратное повторение
Может еще одну промежуточную врменную таблицу попробовать сделать?
Хорого бы также снять AWR, ASH или просто trace+tkprof.
И еще не нравится троекратное повторение
select device_id, profile_id, param_id, num
, max(id) keep (dense_rank last order by datetime) id
, max(value) keep (dense_rank last order by datetime) value
, max(datetime) datetime
from ae_state_tmp
group by device_id, profile_id, param_id, num
Может еще одну промежуточную врменную таблицу попробовать сделать?
Хорого бы также снять AWR, ASH или просто trace+tkprof.
0
Повторение самому особо не нравится, буду думать как сделать получше.
Трейсов не обещаю, скорее всего, в ближайшее время будет не до них. Если будет время, сниму
Трейсов не обещаю, скорее всего, в ближайшее время будет не до них. Если будет время, сниму
0
Трейсы, обработанные tkprof:
plsql
TKPROF: Release 10.2.0.3.0 - Production on Wed Oct 23 11:54:34 2013
Copyright (c) 1982, 2005, Oracle. All rights reserved.
Trace file: plsql.trc
Sort options: default
********************************************************************************
count = number of times OCI procedure was executed
cpu = cpu time in seconds executing
elapsed = elapsed time in seconds executing
disk = number of physical reads of buffers from disk
query = number of buffers gotten for consistent read
current = number of buffers gotten in current mode (usually for update)
rows = number of rows processed by the fetch or execute call
********************************************************************************
begin ae_monitoring.addValue(:1,:2,:3,:4,:5); end;
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 3000 4.23 4.13 7 102942 6615 3000
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 3001 4.23 4.13 7 102942 6615 3000
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 977
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 3000 0.00 0.00
SQL*Net message from client 3000 0.00 1.19
latch: library cache 4 0.00 0.00
********************************************************************************
SELECT D.TYPE_ID, R.OWNER_ID
FROM
AE_PROFILE_DETAIL D INNER JOIN AE_RESOURCE_TYPE R ON (R.ID = D.TYPE_ID)
WHERE D.PROFILE_ID = :B2 AND D.PARAM_ID = :B1
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 3000 0.26 0.26 0 0 0 0
Fetch 3000 0.08 0.07 0 12000 0 3000
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 6001 0.34 0.33 0 12000 0 3000
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 977 (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
3000 NESTED LOOPS (cr=12000 pr=0 pw=0 time=79652 us)
3000 TABLE ACCESS BY INDEX ROWID AE_PROFILE_DETAIL (cr=6000 pr=0 pw=0 time=43305 us)
3000 INDEX RANGE SCAN AE_PROFILE_DETAIL_PARAM_FK (cr=3000 pr=0 pw=0 time=24348 us)(object id 824918)
3000 TABLE ACCESS BY INDEX ROWID AE_RESOURCE_TYPE (cr=6000 pr=0 pw=0 time=25130 us)
3000 INDEX UNIQUE SCAN AE_RESOURCE_TYPE_PK (cr=3000 pr=0 pw=0 time=11649 us)(object id 823579)
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 1 0.00 0.00
SQL*Net message from client 1 5.92 5.92
********************************************************************************
SELECT R.ID, R.NAME
FROM
AE_RESOURCE R WHERE R.DEVICE_ID = :B3 AND R.RES_NUM = :B2 AND R.TYPE_ID =
:B1 AND R.START_DATE <= SYSDATE AND SYSDATE <= NVL(R.END_DATE, SYSDATE + 1)
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 3000 0.34 0.34 0 0 0 0
Fetch 3000 0.14 0.15 0 53000 0 3000
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 6001 0.48 0.49 0 53000 0 3000
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 977 (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
3000 TABLE ACCESS BY INDEX ROWID AE_RESOURCE (cr=53000 pr=0 pw=0 time=155742 us)
102000 INDEX RANGE SCAN AE_RES_DEV_TYPE_FK (cr=50000 pr=0 pw=0 time=173617 us)(object id 823581)
********************************************************************************
SELECT S.VALUE
FROM
AE_STATE S WHERE S.RES_ID = :B2 AND S.PARAM_ID = :B1
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 2000 0.15 0.17 0 0 0 0
Fetch 2000 0.03 0.02 0 7900 0 1899
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4001 0.19 0.20 0 7900 0 1899
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 977 (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
1899 TABLE ACCESS BY INDEX ROWID AE_STATE (cr=7900 pr=0 pw=0 time=31492 us)
1899 INDEX RANGE SCAN AE_STATE_RES_FK (cr=6001 pr=0 pw=0 time=19439 us)(object id 813807)
********************************************************************************
SELECT L.TYPE_ID, L.ID
FROM
AE_PARAMETER P INNER JOIN AE_DOMAIN D ON (D.ID = P.DOMAIN_ID) INNER JOIN
AE_STATE_POLICY L ON (L.ID = D.POLICY_ID) WHERE P.ID = :B1
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 2000 0.11 0.11 0 0 0 0
Fetch 2000 0.04 0.05 0 12000 0 2000
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4001 0.16 0.17 0 12000 0 2000
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 977 (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
2000 NESTED LOOPS (cr=12000 pr=0 pw=0 time=62322 us)
2000 NESTED LOOPS (cr=8000 pr=0 pw=0 time=42519 us)
2000 TABLE ACCESS BY INDEX ROWID AE_PARAMETER (cr=4000 pr=0 pw=0 time=21499 us)
2000 INDEX UNIQUE SCAN AE_PARAMETER_PK (cr=2000 pr=0 pw=0 time=11550 us)(object id 812977)
2000 TABLE ACCESS BY INDEX ROWID AE_DOMAIN (cr=4000 pr=0 pw=0 time=14021 us)
2000 INDEX UNIQUE SCAN AE_DOMAIN_PK (cr=2000 pr=0 pw=0 time=6109 us)(object id 814562)
2000 TABLE ACCESS BY INDEX ROWID AE_STATE_POLICY (cr=4000 pr=0 pw=0 time=12629 us)
2000 INDEX UNIQUE SCAN AE_STATE_POLICY_PK (cr=2000 pr=0 pw=0 time=5458 us)(object id 826206)
********************************************************************************
SELECT COUNT(*)
FROM
AE_THRESHOLD T WHERE T.POLICY_ID = :B6 AND (( T.TYPE_ID = :B5 AND :B1 <=
T.VALUE AND :B2 >= T.VALUE ) OR ( T.TYPE_ID = :B4 AND :B1 >= T.VALUE AND
:B2 <= T.VALUE ) OR ( T.TYPE_ID = :B3 AND ABS(:B2 - :B1 ) >= T.VALUE ))
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 2000 0.65 0.63 0 0 0 0
Fetch 2000 0.03 0.02 0 3000 0 2000
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4001 0.69 0.66 0 3000 0 2000
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 977 (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
2000 SORT AGGREGATE (cr=3000 pr=0 pw=0 time=37842 us)
900 TABLE ACCESS BY INDEX ROWID AE_THRESHOLD (cr=3000 pr=0 pw=0 time=25375 us)
1000 INDEX RANGE SCAN AE_THRESHOLD_PROFILE_FK (cr=2000 pr=0 pw=0 time=13731 us)(object id 825819)
********************************************************************************
INSERT INTO AE_STATE_LOG(ID, RES_ID, PARAM_ID, VALUE)
VALUES
(AE_STATE_LOG_SEQ.NEXTVAL, :B6 , :B5 , DECODE(:B4 , :B3 , NVL(:B2 , :B1 ),
:B1 ))
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1100 0.31 0.30 5 22 3524 1100
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 1101 0.31 0.30 5 22 3524 1100
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 977 (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
1100 SEQUENCE AE_STATE_LOG_SEQ (cr=110 pr=0 pw=0 time=40594 us)
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
db file sequential read 5 0.00 0.00
********************************************************************************
UPDATE AE_STATE SET VALUE = :B3 , DATETIME = CURRENT_TIMESTAMP
WHERE
RES_ID = :B2 AND PARAM_ID = :B1
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 2000 0.32 0.31 0 8899 1945 1899
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2001 0.32 0.31 0 8899 1945 1899
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 977 (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
0 UPDATE AE_STATE (cr=8899 pr=0 pw=0 time=87651 us)
1899 TABLE ACCESS BY INDEX ROWID AE_STATE (cr=8899 pr=0 pw=0 time=37765 us)
1899 INDEX RANGE SCAN AE_STATE_RES_FK (cr=7000 pr=0 pw=0 time=26031 us)(object id 813807)
********************************************************************************
INSERT INTO AE_STATE(ID, PARAM_ID, RES_ID, VALUE)
VALUES
(AE_STATE_SEQ.NEXTVAL, :B3 , :B2 , :B1 )
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 101 0.02 0.02 2 1 1025 101
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 102 0.02 0.02 2 1 1025 101
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 977 (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
101 SEQUENCE AE_STATE_SEQ (cr=10 pr=0 pw=0 time=4478 us)
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
db file sequential read 2 0.00 0.00
********************************************************************************
SELECT R.ID
FROM
AE_RESOURCE R WHERE R.DEVICE_ID = :B2 AND R.TYPE_ID = :B1
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 2000 0.19 0.16 0 0 0 0
Fetch 2000 0.03 0.02 0 6000 0 2000
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4001 0.23 0.19 0 6000 0 2000
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 977 (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
2000 TABLE ACCESS BY INDEX ROWID AE_RESOURCE (cr=6000 pr=0 pw=0 time=26524 us)
2000 INDEX RANGE SCAN AE_RES_DEV_TYPE_FK (cr=4000 pr=0 pw=0 time=16514 us)(object id 823581)
********************************************************************************
update seq$ set increment$=:2,minvalue=:3,maxvalue=:4,cycle#=:5,order$=:6,
cache=:7,highwater=:8,audit$=:9,flags=:10
where
obj#=:1
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 60 0.00 0.00 0 0 0 0
Execute 60 0.02 0.02 0 120 121 60
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 120 0.02 0.02 0 120 121 60
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: CHOOSE
Parsing user id: SYS (recursive depth: 2)
Rows Row Source Operation
------- ---------------------------------------------------
1 UPDATE SEQ$ (cr=2 pr=0 pw=0 time=735 us)
1 INDEX UNIQUE SCAN I_SEQ1 (cr=2 pr=0 pw=0 time=36 us)(object id 102)
********************************************************************************
OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 3000 4.23 4.13 7 102942 6615 3000
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 3001 4.23 4.13 7 102942 6615 3000
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 3002 0.00 0.00
SQL*Net message from client 3002 5.92 7.12
latch: library cache 4 0.00 0.00
log file sync 1 0.00 0.00
OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 69 0.00 0.00 0 0 0 0
Execute 17261 2.42 2.36 7 9042 6615 3160
Fetch 14000 0.38 0.37 0 93900 0 13899
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 31330 2.81 2.74 7 102942 6615 17059
Misses in library cache during parse: 10
Misses in library cache during execute: 10
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
db file sequential read 7 0.00 0.00
10 user SQL statements in session.
60 internal SQL statements in session.
70 SQL statements in session.
********************************************************************************
Trace file: plsql.trc
Trace file compatibility: 10.01.00
Sort options: default
1 session in tracefile.
10 user SQL statements in trace file.
60 internal SQL statements in trace file.
70 SQL statements in trace file.
11 unique SQL statements in trace file.
453925 lines in trace file.
5 elapsed seconds in trace file.
collection
TKPROF: Release 10.2.0.3.0 - Production on Wed Oct 23 12:03:56 2013
Copyright (c) 1982, 2005, Oracle. All rights reserved.
Trace file: collection.trc
Sort options: default
********************************************************************************
count = number of times OCI procedure was executed
cpu = cpu time in seconds executing
elapsed = elapsed time in seconds executing
disk = number of physical reads of buffers from disk
query = number of buffers gotten for consistent read
current = number of buffers gotten in current mode (usually for update)
rows = number of rows processed by the fetch or execute call
********************************************************************************
begin :1 := dbms_pickler.get_type_shape(:2,:3,:4,:5,:6,:7); :8 :=
dbms_pickler.get_format(:9); end;
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.01 0.01 0 35 0 1
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.01 0.01 0 35 0 1
Misses in library cache during parse: 0
Optimizer mode: ALL_ROWS
Parsing user id: 977
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 1 0.00 0.00
SQL*Net message from client 1 0.04 0.04
********************************************************************************
select i.obj#,i.ts#,i.file#,i.block#,i.intcols,i.type#,i.flags,i.property,
i.pctfree$,i.initrans,i.maxtrans,i.blevel,i.leafcnt,i.distkey,i.lblkkey,
i.dblkkey,i.clufac,i.cols,i.analyzetime,i.samplesize,i.dataobj#,
nvl(i.degree,1),nvl(i.instances,1),i.rowcnt,mod(i.pctthres$,256),
i.indmethod#,i.trunccnt,nvl(c.unicols,0),nvl(c.deferrable#+c.valid#,0),
nvl(i.spare1,i.intcols),i.spare4,i.spare2,i.spare6,decode(i.pctthres$,null,
null,mod(trunc(i.pctthres$/256),256)),ist.cachedblk,ist.cachehit,
ist.logicalread
from
ind$ i, ind_stats$ ist, (select enabled, min(cols) unicols,
min(to_number(bitand(defer,1))) deferrable#,min(to_number(bitand(defer,4)))
valid# from cdef$ where obj#=:1 and enabled > 1 group by enabled) c where
i.obj#=c.enabled(+) and i.obj# = ist.obj#(+) and i.bo#=:1 order by i.obj#
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 2 0.00 0.00 0 8 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4 0.00 0.00 0 8 0 1
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: CHOOSE
Parsing user id: SYS (recursive depth: 2)
Rows Row Source Operation
------- ---------------------------------------------------
1 SORT ORDER BY (cr=8 pr=0 pw=0 time=769 us)
1 HASH JOIN OUTER (cr=8 pr=0 pw=0 time=713 us)
1 NESTED LOOPS OUTER (cr=5 pr=0 pw=0 time=121 us)
1 TABLE ACCESS CLUSTER IND$ (cr=4 pr=0 pw=0 time=100 us)
1 INDEX UNIQUE SCAN I_OBJ# (cr=2 pr=0 pw=0 time=48 us)(object id 3)
0 TABLE ACCESS BY INDEX ROWID IND_STATS$ (cr=1 pr=0 pw=0 time=14 us)
0 INDEX UNIQUE SCAN I_IND_STATS$_OBJ# (cr=1 pr=0 pw=0 time=10 us)(object id 711)
0 VIEW (cr=3 pr=0 pw=0 time=110 us)
0 SORT GROUP BY (cr=3 pr=0 pw=0 time=108 us)
0 TABLE ACCESS CLUSTER CDEF$ (cr=3 pr=0 pw=0 time=59 us)
1 INDEX UNIQUE SCAN I_COBJ# (cr=2 pr=0 pw=0 time=34 us)(object id 30)
********************************************************************************
select pos#,intcol#,col#,spare1,bo#,spare2
from
icol$ where obj#=:1
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 2 0.00 0.00 0 4 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4 0.00 0.00 0 4 0 1
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: CHOOSE
Parsing user id: SYS (recursive depth: 2)
Rows Row Source Operation
------- ---------------------------------------------------
1 TABLE ACCESS BY INDEX ROWID ICOL$ (cr=4 pr=0 pw=0 time=57 us)
1 INDEX RANGE SCAN I_ICOL1 (cr=3 pr=0 pw=0 time=67 us)(object id 40)
********************************************************************************
select name,intcol#,segcol#,type#,length,nvl(precision#,0),decode(type#,2,
nvl(scale,-127/*MAXSB1MINAL*/),178,scale,179,scale,180,scale,181,scale,182,
scale,183,scale,231,scale,0),null$,fixedstorage,nvl(deflength,0),default$,
rowid,col#,property, nvl(charsetid,0),nvl(charsetform,0),spare1,spare2,
nvl(spare3,0)
from
col$ where obj#=:1 order by intcol#
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 4 0.00 0.00 0 3 0 3
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 6 0.00 0.00 0 3 0 3
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: CHOOSE
Parsing user id: SYS (recursive depth: 2)
Rows Row Source Operation
------- ---------------------------------------------------
3 SORT ORDER BY (cr=3 pr=0 pw=0 time=57 us)
3 TABLE ACCESS CLUSTER COL$ (cr=3 pr=0 pw=0 time=27 us)
1 INDEX UNIQUE SCAN I_OBJ# (cr=2 pr=0 pw=0 time=11 us)(object id 3)
********************************************************************************
select obj#,type#,ctime,mtime,stime,status,dataobj#,flags,oid$, spare1,
spare2
from
obj$ where owner#=:1 and name=:2 and namespace=:3 and remoteowner is null
and linkname is null and subname is null
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 0.00 0.00 0 4 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 3 0.00 0.00 0 4 0 1
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: CHOOSE
Parsing user id: SYS (recursive depth: 2)
Rows Row Source Operation
------- ---------------------------------------------------
1 TABLE ACCESS BY INDEX ROWID OBJ$ (cr=4 pr=0 pw=0 time=77 us)
1 INDEX RANGE SCAN I_OBJ2 (cr=3 pr=0 pw=0 time=59 us)(object id 37)
********************************************************************************
select /*+ rule */ bucket_cnt, row_cnt, cache_cnt, null_cnt, timestamp#,
sample_size, minimum, maximum, distcnt, lowval, hival, density, col#,
spare1, spare2, avgcln
from
hist_head$ where obj#=:1 and intcol#=:2
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 2 0.00 0.00 0 0 0 0
Fetch 2 0.00 0.00 0 8 0 2
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 5 0.00 0.00 0 8 0 2
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: RULE
Parsing user id: SYS (recursive depth: 2)
Rows Row Source Operation
------- ---------------------------------------------------
1 TABLE ACCESS BY INDEX ROWID HIST_HEAD$ (cr=4 pr=0 pw=0 time=107 us)
1 INDEX RANGE SCAN I_HH_OBJ#_INTCOL# (cr=3 pr=0 pw=0 time=85 us)(object id 257)
********************************************************************************
select metadata
from
kopm$ where name='DB_FDO'
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 0.00 0.00 0 2 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 3 0.00 0.00 0 2 0 1
Misses in library cache during parse: 1
Optimizer mode: CHOOSE
Parsing user id: SYS (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
1 TABLE ACCESS BY INDEX ROWID KOPM$ (cr=2 pr=0 pw=0 time=38 us)
1 INDEX UNIQUE SCAN I_KOPM1 (cr=1 pr=0 pw=0 time=21 us)(object id 365)
********************************************************************************
begin :1 := dbms_pickler.get_type_shape(:2,:3,:4,:5,:6,:7); end;
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 3 0 1
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.00 0.00 0 3 0 1
Misses in library cache during parse: 0
Optimizer mode: ALL_ROWS
Parsing user id: 977
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 1 0.00 0.00
SQL*Net message from client 1 0.00 0.00
********************************************************************************
SELECT INSTANTIABLE, supertype_owner, supertype_name, LOCAL_ATTRIBUTES
FROM
all_types WHERE type_name = :1 AND owner = :2
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.01 0 2 0 0
Fetch 1 0.00 0.00 0 9 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 3 0.00 0.01 0 11 0 1
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 977
Rows Row Source Operation
------- ---------------------------------------------------
1 VIEW ALL_TYPES (cr=9 pr=0 pw=0 time=327 us)
1 SORT UNIQUE (cr=9 pr=0 pw=0 time=322 us)
1 UNION-ALL (cr=9 pr=0 pw=0 time=280 us)
1 FILTER (cr=9 pr=0 pw=0 time=262 us)
1 NESTED LOOPS OUTER (cr=9 pr=0 pw=0 time=252 us)
1 NESTED LOOPS OUTER (cr=9 pr=0 pw=0 time=242 us)
1 NESTED LOOPS (cr=9 pr=0 pw=0 time=233 us)
1 NESTED LOOPS (cr=6 pr=0 pw=0 time=130 us)
1 TABLE ACCESS BY INDEX ROWID USER$ (cr=2 pr=0 pw=0 time=52 us)
1 INDEX UNIQUE SCAN I_USER1 (cr=1 pr=0 pw=0 time=29 us)(object id 44)
1 TABLE ACCESS BY INDEX ROWID OBJ$ (cr=4 pr=0 pw=0 time=75 us)
1 INDEX RANGE SCAN I_OBJ2 (cr=3 pr=0 pw=0 time=46 us)(object id 37)
1 TABLE ACCESS BY INDEX ROWID TYPE$ (cr=3 pr=0 pw=0 time=98 us)
1 INDEX UNIQUE SCAN I_TYPE2 (cr=2 pr=0 pw=0 time=75 us)(object id 185)
0 TABLE ACCESS BY INDEX ROWID OBJ$ (cr=0 pr=0 pw=0 time=4 us)
0 INDEX RANGE SCAN I_OBJ3 (cr=0 pr=0 pw=0 time=2 us)(object id 38)
0 TABLE ACCESS CLUSTER USER$ (cr=0 pr=0 pw=0 time=5 us)
0 INDEX UNIQUE SCAN I_USER# (cr=0 pr=0 pw=0 time=2 us)(object id 11)
0 NESTED LOOPS (cr=0 pr=0 pw=0 time=0 us)
0 INDEX RANGE SCAN I_OBJAUTH1 (cr=0 pr=0 pw=0 time=0 us)(object id 103)
0 FIXED TABLE FULL X$KZSRO (cr=0 pr=0 pw=0 time=0 us)
0 FIXED TABLE FULL X$KZSPR (cr=0 pr=0 pw=0 time=0 us)
0 FILTER (cr=0 pr=0 pw=0 time=4 us)
0 FILTER (cr=0 pr=0 pw=0 time=2 us)
0 NESTED LOOPS OUTER (cr=0 pr=0 pw=0 time=0 us)
0 NESTED LOOPS OUTER (cr=0 pr=0 pw=0 time=0 us)
0 MERGE JOIN CARTESIAN (cr=0 pr=0 pw=0 time=0 us)
0 NESTED LOOPS (cr=0 pr=0 pw=0 time=0 us)
0 TABLE ACCESS BY INDEX ROWID OBJ$ (cr=0 pr=0 pw=0 time=0 us)
0 INDEX SKIP SCAN I_OBJ2 (cr=0 pr=0 pw=0 time=0 us)(object id 37)
0 TABLE ACCESS BY INDEX ROWID TYPE$ (cr=0 pr=0 pw=0 time=0 us)
0 INDEX UNIQUE SCAN I_TYPE2 (cr=0 pr=0 pw=0 time=0 us)(object id 185)
0 BUFFER SORT (cr=0 pr=0 pw=0 time=0 us)
0 INDEX FULL SCAN I_USER1 (cr=0 pr=0 pw=0 time=0 us)(object id 44)
0 TABLE ACCESS BY INDEX ROWID OBJ$ (cr=0 pr=0 pw=0 time=0 us)
0 INDEX RANGE SCAN I_OBJ3 (cr=0 pr=0 pw=0 time=0 us)(object id 38)
0 TABLE ACCESS CLUSTER USER$ (cr=0 pr=0 pw=0 time=0 us)
0 INDEX UNIQUE SCAN I_USER# (cr=0 pr=0 pw=0 time=0 us)(object id 11)
0 NESTED LOOPS (cr=0 pr=0 pw=0 time=0 us)
0 INDEX RANGE SCAN I_OBJAUTH1 (cr=0 pr=0 pw=0 time=0 us)(object id 103)
0 FIXED TABLE FULL X$KZSRO (cr=0 pr=0 pw=0 time=0 us)
0 FIXED TABLE FULL X$KZSPR (cr=0 pr=0 pw=0 time=0 us)
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 2 0.00 0.00
SQL*Net message from client 2 0.06 0.06
********************************************************************************
select text
from
view$ where rowid=:1
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 0.00 0.00 1 2 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 3 0.00 0.00 1 2 0 1
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: CHOOSE
Parsing user id: SYS (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
1 TABLE ACCESS BY USER ROWID VIEW$ (cr=1 pr=1 pw=0 time=706 us)
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
db file sequential read 1 0.00 0.00
********************************************************************************
begin ae_monitoring.addValues(:1); end;
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 4.33 4.27 5 136013 6610 1
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 4.33 4.27 5 136013 6610 1
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 977
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net more data from client 41 0.00 0.00
SQL*Net message to client 1 0.00 0.00
SQL*Net message from client 1 0.00 0.00
********************************************************************************
SELECT D.TYPE_ID, R.OWNER_ID
FROM
AE_PROFILE_DETAIL D INNER JOIN AE_RESOURCE_TYPE R ON (R.ID = D.TYPE_ID)
WHERE D.PROFILE_ID = :B2 AND D.PARAM_ID = :B1
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 3000 0.32 0.35 0 0 0 0
Fetch 3000 0.08 0.08 0 12000 0 3000
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 6001 0.41 0.44 0 12000 0 3000
Misses in library cache during parse: 0
Optimizer mode: ALL_ROWS
Parsing user id: 977 (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
3000 NESTED LOOPS (cr=12000 pr=0 pw=0 time=93428 us)
3000 TABLE ACCESS BY INDEX ROWID AE_PROFILE_DETAIL (cr=6000 pr=0 pw=0 time=49225 us)
3000 INDEX RANGE SCAN AE_PROFILE_DETAIL_PARAM_FK (cr=3000 pr=0 pw=0 time=27427 us)(object id 824918)
3000 TABLE ACCESS BY INDEX ROWID AE_RESOURCE_TYPE (cr=6000 pr=0 pw=0 time=30294 us)
3000 INDEX UNIQUE SCAN AE_RESOURCE_TYPE_PK (cr=3000 pr=0 pw=0 time=14086 us)(object id 823579)
********************************************************************************
SELECT R.ID, R.NAME
FROM
AE_RESOURCE R WHERE R.DEVICE_ID = :B3 AND R.RES_NUM = :B2 AND R.TYPE_ID =
:B1 AND R.START_DATE <= SYSDATE AND SYSDATE <= NVL(R.END_DATE, SYSDATE + 1)
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 3000 0.44 0.42 0 0 0 0
Fetch 3000 0.22 0.23 0 89000 0 3000
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 6001 0.67 0.65 0 89000 0 3000
Misses in library cache during parse: 0
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 977 (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
3000 TABLE ACCESS BY INDEX ROWID AE_RESOURCE (cr=89000 pr=0 pw=0 time=231911 us)
102000 INDEX RANGE SCAN AE_RES_DEV_TYPE_FK (cr=86000 pr=0 pw=0 time=257510 us)(object id 823581)
********************************************************************************
SELECT S.VALUE
FROM
AE_STATE S WHERE S.RES_ID = :B2 AND S.PARAM_ID = :B1
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 2000 0.20 0.20 0 0 0 0
Fetch 2000 0.02 0.03 0 5899 0 1899
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4001 0.22 0.23 0 5899 0 1899
Misses in library cache during parse: 0
Optimizer mode: ALL_ROWS
Parsing user id: 977 (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
1899 TABLE ACCESS BY INDEX ROWID AE_STATE (cr=5899 pr=0 pw=0 time=32257 us)
1899 INDEX RANGE SCAN AE_STATE_RES_FK (cr=4000 pr=0 pw=0 time=17739 us)(object id 813807)
********************************************************************************
SELECT L.TYPE_ID, L.ID
FROM
AE_PARAMETER P INNER JOIN AE_DOMAIN D ON (D.ID = P.DOMAIN_ID) INNER JOIN
AE_STATE_POLICY L ON (L.ID = D.POLICY_ID) WHERE P.ID = :B1
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 2000 0.14 0.14 0 0 0 0
Fetch 2000 0.07 0.07 0 12000 0 2000
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4001 0.21 0.21 0 12000 0 2000
Misses in library cache during parse: 0
Optimizer mode: ALL_ROWS
Parsing user id: 977 (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
2000 NESTED LOOPS (cr=12000 pr=0 pw=0 time=76757 us)
2000 NESTED LOOPS (cr=8000 pr=0 pw=0 time=52247 us)
2000 TABLE ACCESS BY INDEX ROWID AE_PARAMETER (cr=4000 pr=0 pw=0 time=26209 us)
2000 INDEX UNIQUE SCAN AE_PARAMETER_PK (cr=2000 pr=0 pw=0 time=13964 us)(object id 812977)
2000 TABLE ACCESS BY INDEX ROWID AE_DOMAIN (cr=4000 pr=0 pw=0 time=17395 us)
2000 INDEX UNIQUE SCAN AE_DOMAIN_PK (cr=2000 pr=0 pw=0 time=7485 us)(object id 814562)
2000 TABLE ACCESS BY INDEX ROWID AE_STATE_POLICY (cr=4000 pr=0 pw=0 time=15696 us)
2000 INDEX UNIQUE SCAN AE_STATE_POLICY_PK (cr=2000 pr=0 pw=0 time=6738 us)(object id 826206)
********************************************************************************
SELECT COUNT(*)
FROM
AE_THRESHOLD T WHERE T.POLICY_ID = :B6 AND (( T.TYPE_ID = :B5 AND :B1 <=
T.VALUE AND :B2 >= T.VALUE ) OR ( T.TYPE_ID = :B4 AND :B1 >= T.VALUE AND
:B2 <= T.VALUE ) OR ( T.TYPE_ID = :B3 AND ABS(:B2 - :B1 ) >= T.VALUE ))
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 2000 0.82 0.78 0 0 0 0
Fetch 2000 0.03 0.03 0 3000 0 2000
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4001 0.85 0.81 0 3000 0 2000
Misses in library cache during parse: 0
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 977 (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
2000 SORT AGGREGATE (cr=3000 pr=0 pw=0 time=45744 us)
900 TABLE ACCESS BY INDEX ROWID AE_THRESHOLD (cr=3000 pr=0 pw=0 time=30904 us)
1000 INDEX RANGE SCAN AE_THRESHOLD_PROFILE_FK (cr=2000 pr=0 pw=0 time=16924 us)(object id 825819)
********************************************************************************
INSERT INTO AE_STATE_LOG(ID, RES_ID, PARAM_ID, VALUE)
VALUES
(AE_STATE_LOG_SEQ.NEXTVAL, :B6 , :B5 , DECODE(:B4 , :B3 , NVL(:B2 , :B1 ),
:B1 ))
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1100 0.37 0.37 5 24 3515 1100
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 1101 0.37 0.37 5 24 3515 1100
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 977 (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
1100 SEQUENCE AE_STATE_LOG_SEQ (cr=110 pr=0 pw=0 time=46015 us)
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
db file sequential read 5 0.00 0.00
********************************************************************************
update seq$ set increment$=:2,minvalue=:3,maxvalue=:4,cycle#=:5,order$=:6,
cache=:7,highwater=:8,audit$=:9,flags=:10
where
obj#=:1
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 60 0.00 0.00 0 0 0 0
Execute 60 0.03 0.02 0 120 121 60
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 120 0.03 0.02 0 120 121 60
Misses in library cache during parse: 0
Optimizer mode: CHOOSE
Parsing user id: SYS (recursive depth: 2)
Rows Row Source Operation
------- ---------------------------------------------------
1 UPDATE SEQ$ (cr=2 pr=0 pw=0 time=330 us)
1 INDEX UNIQUE SCAN I_SEQ1 (cr=2 pr=0 pw=0 time=35 us)(object id 102)
********************************************************************************
UPDATE AE_STATE SET VALUE = :B3 , DATETIME = CURRENT_TIMESTAMP
WHERE
RES_ID = :B2 AND PARAM_ID = :B1
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 2000 0.39 0.37 0 5899 1945 1899
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2001 0.39 0.37 0 5899 1945 1899
Misses in library cache during parse: 0
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 977 (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
0 UPDATE AE_STATE (cr=5899 pr=0 pw=0 time=97694 us)
1899 TABLE ACCESS BY INDEX ROWID AE_STATE (cr=5899 pr=0 pw=0 time=36393 us)
1899 INDEX RANGE SCAN AE_STATE_RES_FK (cr=4000 pr=0 pw=0 time=22106 us)(object id 813807)
********************************************************************************
INSERT INTO AE_STATE(ID, PARAM_ID, RES_ID, VALUE)
VALUES
(AE_STATE_SEQ.NEXTVAL, :B3 , :B2 , :B1 )
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 101 0.02 0.02 0 3 1028 101
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 102 0.02 0.02 0 3 1028 101
Misses in library cache during parse: 0
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 977 (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
101 SEQUENCE AE_STATE_SEQ (cr=10 pr=0 pw=0 time=5015 us)
********************************************************************************
SELECT R.ID
FROM
AE_RESOURCE R WHERE R.DEVICE_ID = :B2 AND R.TYPE_ID = :B1
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 2000 0.19 0.20 0 0 0 0
Fetch 2000 0.05 0.03 0 8000 0 2000
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4001 0.24 0.24 0 8000 0 2000
Misses in library cache during parse: 0
Optimizer mode: ALL_ROWS
Parsing user id: 977 (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
2000 TABLE ACCESS BY INDEX ROWID AE_RESOURCE (cr=8000 pr=0 pw=0 time=40457 us)
2000 INDEX RANGE SCAN AE_RES_DEV_TYPE_FK (cr=6000 pr=0 pw=0 time=27874 us)(object id 823581)
********************************************************************************
COMMIT WRITE NOWAIT
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 1 0
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.00 0.00 0 0 1 0
Misses in library cache during parse: 0
Parsing user id: 977 (recursive depth: 1)
********************************************************************************
OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 4 0.00 0.00 0 0 0 0
Execute 4 4.35 4.31 5 136053 6610 3
Fetch 1 0.00 0.00 0 9 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 9 4.35 4.31 5 136062 6610 4
Misses in library cache during parse: 2
Misses in library cache during execute: 2
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 6 0.00 0.00
SQL*Net message from client 6 0.23 0.34
SQL*Net more data from client 41 0.00 0.00
OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 77 0.00 0.00 0 0 0 0
Execute 17270 2.97 2.92 5 6046 6610 3160
Fetch 14013 0.49 0.49 1 129930 0 13909
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 31360 3.48 3.43 6 135976 6610 17069
Misses in library cache during parse: 8
Misses in library cache during execute: 11
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
db file sequential read 6 0.00 0.00
14 user SQL statements in session.
68 internal SQL statements in session.
82 SQL statements in session.
********************************************************************************
Trace file: collection.trc
Trace file compatibility: 10.01.00
Sort options: default
1 session in tracefile.
14 user SQL statements in trace file.
68 internal SQL statements in trace file.
82 SQL statements in trace file.
22 unique SQL statements in trace file.
364287 lines in trace file.
4 elapsed seconds in trace file.
temporary
TKPROF: Release 10.2.0.3.0 - Production on Wed Oct 23 11:56:53 2013
Copyright (c) 1982, 2005, Oracle. All rights reserved.
Trace file: temporary.trc
Sort options: default
********************************************************************************
count = number of times OCI procedure was executed
cpu = cpu time in seconds executing
elapsed = elapsed time in seconds executing
disk = number of physical reads of buffers from disk
query = number of buffers gotten for consistent read
current = number of buffers gotten in current mode (usually for update)
rows = number of rows processed by the fetch or execute call
********************************************************************************
The following statements encountered a error during parse:
SELECT 1 FROM DUAL WHERE d.device_id = s.device_id and d.profile_id = s.profile_id and d.param_id = s.param_id and d.num = s.num
Error encountered: ORA-00904
--------------------------------------------------------------------------------
SELECT 1 FROM DUAL WHERE D.DEVICE_ID = S.DEVICE_ID AND D.RES_NUM = S.NUM AND D.TYPE_ID = S.TYPE_ID AND D.START_DATE <= SYSDATE AND SYSDATE <= NVL(D.END_DATE, SYSDATE + 1)
Error encountered: ORA-00904
--------------------------------------------------------------------------------
SELECT 1 FROM DUAL WHERE D.RES_ID = S.RES_ID AND D.PARAM_ID = S.PARAM_I
Error encountered: ORA-00904
********************************************************************************
merge into ae_state_tmp d using ( select :1 id,:2 device_id,:3 profile_id,:4
param_id,:5 num,:6 value from dual ) s on ( d.device_id =
s.device_id and d.profile_id = s.profile_id and d.param_id =
s.param_id and d.num = s.num ) when matched then update set d.value =
s.value when not matched then insert (id, device_id, profile_id, param_id,
num, value) values (s.id, s.device_id, s.profile_id, s.param_id, s.num,
s.value)
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1000 1.02 1.01 0 9002 3503 3000
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 1001 1.02 1.01 0 9002 3503 3000
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 977
Rows Row Source Operation
------- ---------------------------------------------------
6000 MERGE AE_STATE_TMP (cr=9011 pr=0 pw=0 time=247489 us)
3000 VIEW (cr=9000 pr=0 pw=0 time=152643 us)
3000 NESTED LOOPS OUTER (cr=9000 pr=0 pw=0 time=142098 us)
3000 FAST DUAL (cr=0 pr=0 pw=0 time=6854 us)
2799 TABLE ACCESS FULL AE_STATE_TMP (cr=9000 pr=0 pw=0 time=121548 us)
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 1000 0.00 0.00
SQL*Net message from client 1000 0.00 0.41
********************************************************************************
select file#
from
file$ where ts#=:1
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 5 0.00 0.00 0 9 0 4
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 7 0.00 0.00 0 9 0 4
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: CHOOSE
Parsing user id: SYS (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
4 TABLE ACCESS BY INDEX ROWID FILE$ (cr=9 pr=0 pw=0 time=57 us)
4 INDEX RANGE SCAN I_FILE2 (cr=5 pr=0 pw=0 time=44 us)(object id 42)
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 1 0.00 0.00
SQL*Net message from client 1 0.00 0.00
********************************************************************************
begin ae_monitoring.saveValues; end;
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 1
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.00 0.00 0 0 0 1
Misses in library cache during parse: 0
Optimizer mode: ALL_ROWS
Parsing user id: 977
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 1 0.00 0.00
SQL*Net message from client 1 0.00 0.00
********************************************************************************
MERGE INTO AE_RESOURCE D USING ( SELECT T.ID, T.DEVICE_ID, T.NUM, DECODE(O.ID,
NULL, T.NUM, T.VALUE) NAME, P.TYPE_ID, O.ID OWNER_ID FROM AE_STATE_TMP T
INNER JOIN AE_PROFILE_DETAIL P ON (P.PROFILE_ID = T.PROFILE_ID AND
P.PARAM_ID = T.PARAM_ID) INNER JOIN AE_RESOURCE_TYPE R ON (R.ID = P.TYPE_ID)
LEFT JOIN AE_RESOURCE O ON (O.DEVICE_ID = T.DEVICE_ID AND O.TYPE_ID =
R.OWNER_ID) WHERE T.PARAM_ID = :B1 OR O.ID IS NULL ) S ON ( D.DEVICE_ID =
S.DEVICE_ID AND D.RES_NUM = S.NUM AND D.TYPE_ID = S.TYPE_ID AND
D.START_DATE <= SYSDATE AND SYSDATE <= NVL(D.END_DATE, SYSDATE + 1) ) WHEN
MATCHED THEN UPDATE SET D.TMP_ID = S.ID WHERE D.NAME <> S.NAME WHEN NOT
MATCHED THEN INSERT (ID, DEVICE_ID, OWNER_ID, TYPE_ID, RES_NUM, NAME)
VALUES (AE_RESOURCE_SEQ.NEXTVAL, S.DEVICE_ID, S.OWNER_ID, S.TYPE_ID, S.NUM,
S.NAME)
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.09 0.10 43 19314 9 0
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.09 0.10 43 19314 9 0
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 977 (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
2 MERGE AE_RESOURCE (cr=19322 pr=43 pw=0 time=95507 us)
101 VIEW (cr=19322 pr=43 pw=0 time=42246 us)
101 SEQUENCE AE_RESOURCE_SEQ (cr=19322 pr=43 pw=0 time=41342 us)
101 FILTER (cr=19312 pr=43 pw=0 time=40413 us)
201 NESTED LOOPS OUTER (cr=19312 pr=43 pw=0 time=76907 us)
201 NESTED LOOPS OUTER (cr=9662 pr=22 pw=0 time=49248 us)
201 VIEW (cr=12 pr=4 pw=0 time=16093 us)
201 HASH JOIN (cr=12 pr=4 pw=0 time=15692 us)
6 MERGE JOIN (cr=9 pr=4 pw=0 time=13964 us)
2 TABLE ACCESS BY INDEX ROWID AE_RESOURCE_TYPE (cr=2 pr=0 pw=0 time=53 us)
2 INDEX FULL SCAN AE_RESOURCE_TYPE_PK (cr=1 pr=0 pw=0 time=27 us)(object id 823579)
6 SORT JOIN (cr=7 pr=4 pw=0 time=13911 us)
6 TABLE ACCESS FULL AE_PROFILE_DETAIL (cr=7 pr=4 pw=0 time=13562 us)
201 TABLE ACCESS FULL AE_STATE_TMP (cr=3 pr=0 pw=0 time=430 us)
201 TABLE ACCESS BY INDEX ROWID AE_RESOURCE (cr=9650 pr=18 pw=0 time=24101 us)
20301 INDEX RANGE SCAN AE_RES_DEV_FK (cr=9248 pr=18 pw=0 time=9377 us)(object id 823580)
200 TABLE ACCESS BY INDEX ROWID AE_RESOURCE (cr=9650 pr=21 pw=0 time=29764 us)
20301 INDEX RANGE SCAN AE_RES_DEV_FK (cr=9248 pr=21 pw=0 time=7695 us)(object id 823580)
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
db file sequential read 41 0.01 0.01
db file scattered read 1 0.00 0.00
********************************************************************************
SELECT /* OPT_DYN_SAMP */ /*+ ALL_ROWS IGNORE_WHERE_CLAUSE
NO_PARALLEL(SAMPLESUB) opt_param('parallel_execution_enabled', 'false')
NO_PARALLEL_INDEX(SAMPLESUB) NO_SQL_TUNE */ NVL(SUM(C1),:"SYS_B_0"),
NVL(SUM(C2),:"SYS_B_1"), COUNT(DISTINCT C3), NVL(SUM(CASE WHEN C3 IS NULL
THEN :"SYS_B_2" ELSE :"SYS_B_3" END),:"SYS_B_4")
FROM
(SELECT /*+ NO_PARALLEL("T") FULL("T") NO_PARALLEL_INDEX("T") */ :"SYS_B_5"
AS C1, :"SYS_B_6" AS C2, "T"."PROFILE_ID" AS C3 FROM "AE_STATE_TMP" "T")
SAMPLESUB
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 3 0.00 0.00 0 0 0 0
Execute 3 0.00 0.00 0 0 0 0
Fetch 3 0.00 0.00 0 9 0 3
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 9 0.00 0.00 0 9 0 3
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 977 (recursive depth: 2)
Rows Row Source Operation
------- ---------------------------------------------------
1 SORT GROUP BY (cr=3 pr=0 pw=0 time=212 us)
201 TABLE ACCESS FULL AE_STATE_TMP (cr=3 pr=0 pw=0 time=241 us)
********************************************************************************
update seq$ set increment$=:2,minvalue=:3,maxvalue=:4,cycle#=:5,order$=:6,
cache=:7,highwater=:8,audit$=:9,flags=:10
where
obj#=:1
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 10 0.00 0.00 0 0 0 0
Execute 10 0.00 0.00 0 20 21 10
Fetch 0 0.00 0.00 0 0 0 0
------- ------ 0
1) Сорри, глубоко анализировать трейсы некогда, но что броислось в глаза, это фул сканы таблиц из которых (по моему пониманию выших данных) должно выниматься сравнительно мало строк. Либо они настолько маленькие, что одним multiblock read-ом вычитывается вся таблица, либо на справочных таблицах индексов добавиьт не помешало бы.
2) зачем dynamic sampling? Лучше соберите или постройте / импортируйте нормальную статистику по объектам.
3) Из «collection»:
> MERGE JOIN CARTESIAN
ойойой! не знаю что вы там делаете, но чуйкой чую что-то не то.
… Больше не копал, сорри. Но у меня усиленное чувство, смотря на PL/SQL код что там ещё очень много чего можно переписать сильно оптимальнее, убрав / переделав процесс. Но это будет больше логическая / архитектурная оптимизация, чем техническая. Но она, как раз, как правило даёт больше пользы :)
2) зачем dynamic sampling? Лучше соберите или постройте / импортируйте нормальную статистику по объектам.
3) Из «collection»:
> MERGE JOIN CARTESIAN
ойойой! не знаю что вы там делаете, но чуйкой чую что-то не то.
… Больше не копал, сорри. Но у меня усиленное чувство, смотря на PL/SQL код что там ещё очень много чего можно переписать сильно оптимальнее, убрав / переделав процесс. Но это будет больше логическая / архитектурная оптимизация, чем техническая. Но она, как раз, как правило даёт больше пользы :)
0
Обязательно посмотрю трейсы внимательно как только появится свободная минута. Merge Join Cartesian это конечно не правильно.
0
Читал планы, много думал:
Запрос не мой, я только объяву разместил. Непосредственно связан с тем, что в кейсах collection и bulk я передаю данные с клиента массивами. И вряд ли я смогу в этом плане в чем-то переубедить Oracle
SELECT INSTANTIABLE, supertype_owner, supertype_name, LOCAL_ATTRIBUTES
FROM
all_types WHERE type_name = :1 AND owner = :2
...
0 MERGE JOIN CARTESIAN (cr=0 pr=0 pw=0 time=0 us)
0 NESTED LOOPS (cr=0 pr=0 pw=0 time=0 us)
0 TABLE ACCESS BY INDEX ROWID OBJ$ (cr=0 pr=0 pw=0 time=0 us)
0 INDEX SKIP SCAN I_OBJ2 (cr=0 pr=0 pw=0 time=0 us)(object id 37)
0 TABLE ACCESS BY INDEX ROWID TYPE$ (cr=0 pr=0 pw=0 time=0 us)
0 INDEX UNIQUE SCAN I_TYPE2 (cr=0 pr=0 pw=0 time=0 us)(object id 185)
Запрос не мой
0
FULL SCAN-ы по преимуществу идут из таблиц, планируемых маленькими, тут на первый взгляд все нормально.
По поводу dynamic sampling абсолютно согласен
По поводу dynamic sampling абсолютно согласен
0
distinct
TKPROF: Release 10.2.0.3.0 - Production on Wed Oct 23 12:01:38 2013
Copyright (c) 1982, 2005, Oracle. All rights reserved.
Trace file: distinct.trc
Sort options: default
********************************************************************************
count = number of times OCI procedure was executed
cpu = cpu time in seconds executing
elapsed = elapsed time in seconds executing
disk = number of physical reads of buffers from disk
query = number of buffers gotten for consistent read
current = number of buffers gotten in current mode (usually for update)
rows = number of rows processed by the fetch or execute call
********************************************************************************
The following statements encountered a error during parse:
SELECT 1 FROM DUAL WHERE D.DEVICE_ID = S.DEVICE_ID AND D.RES_NUM = S.NUM AND D.TYPE_ID = S.TYPE_ID AND D.START_DATE <= SYSDATE AND SYSDATE <= NVL(D.END_DATE, SYSDATE + 1)
Error encountered: ORA-00904
--------------------------------------------------------------------------------
SELECT 1 FROM DUAL WHERE D.RES_ID = S.RES_ID AND D.PARAM_ID = S.PARAM_I
Error encountered: ORA-00904
********************************************************************************
insert into ae_state_tmp(id, device_id, profile_id, param_id, num, value)
values
(:1,:2,:3,:4,:5,:6)
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1000 0.36 0.33 0 96 6616 3000
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 1001 0.36 0.33 0 96 6616 3000
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 977
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 1000 0.00 0.00
SQL*Net message from client 1000 0.00 0.40
********************************************************************************
begin ae_monitoring.saveValuesDistinct; end;
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 1
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.00 0.00 0 0 0 1
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 977
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 2 0.00 0.00
SQL*Net message from client 2 0.00 0.00
********************************************************************************
MERGE INTO AE_RESOURCE D USING ( SELECT T.ID, T.DEVICE_ID, T.NUM, DECODE(O.ID,
NULL, T.NUM, T.VALUE) NAME, P.TYPE_ID, O.ID OWNER_ID FROM ( SELECT
DEVICE_ID, PROFILE_ID, PARAM_ID, NUM , MAX(ID) KEEP (DENSE_RANK LAST ORDER
BY DATETIME) ID , MAX(VALUE) KEEP (DENSE_RANK LAST ORDER BY DATETIME) VALUE
, MAX(DATETIME) DATETIME FROM AE_STATE_TMP GROUP BY DEVICE_ID, PROFILE_ID,
PARAM_ID, NUM ) T INNER JOIN AE_PROFILE_DETAIL P ON (P.PROFILE_ID =
T.PROFILE_ID AND P.PARAM_ID = T.PARAM_ID) INNER JOIN AE_RESOURCE_TYPE R ON
(R.ID = P.TYPE_ID) LEFT JOIN AE_RESOURCE O ON (O.DEVICE_ID = T.DEVICE_ID
AND O.TYPE_ID = R.OWNER_ID) WHERE T.PARAM_ID = :B1 OR O.ID IS NULL ) S ON (
D.DEVICE_ID = S.DEVICE_ID AND D.RES_NUM = S.NUM AND D.TYPE_ID = S.TYPE_ID
AND D.START_DATE <= SYSDATE AND SYSDATE <= NVL(D.END_DATE, SYSDATE + 1) )
WHEN MATCHED THEN UPDATE SET D.TMP_ID = S.ID WHERE D.NAME <> S.NAME WHEN
NOT MATCHED THEN INSERT (ID, DEVICE_ID, OWNER_ID, TYPE_ID, RES_NUM, NAME)
VALUES (AE_RESOURCE_SEQ.NEXTVAL, S.DEVICE_ID, S.OWNER_ID, S.TYPE_ID, S.NUM,
S.NAME)
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.03 0.02 0 185 10 0
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.03 0.03 0 185 10 0
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 977 (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
2 MERGE AE_RESOURCE (cr=195 pr=0 pw=0 time=16754 us)
101 VIEW (cr=195 pr=0 pw=0 time=15449 us)
101 SEQUENCE AE_RESOURCE_SEQ (cr=195 pr=0 pw=0 time=14346 us)
101 FILTER (cr=183 pr=0 pw=0 time=12655 us)
201 HASH JOIN RIGHT OUTER (cr=183 pr=0 pw=0 time=13552 us)
101 TABLE ACCESS FULL AE_RESOURCE (cr=76 pr=0 pw=0 time=39719 us)
201 HASH JOIN RIGHT OUTER (cr=107 pr=0 pw=0 time=11358 us)
101 TABLE ACCESS FULL AE_RESOURCE (cr=76 pr=0 pw=0 time=9949 us)
201 VIEW (cr=31 pr=0 pw=0 time=9070 us)
201 HASH JOIN (cr=31 pr=0 pw=0 time=8667 us)
6 MERGE JOIN (cr=9 pr=0 pw=0 time=192 us)
2 TABLE ACCESS BY INDEX ROWID AE_RESOURCE_TYPE (cr=2 pr=0 pw=0 time=52 us)
2 INDEX FULL SCAN AE_RESOURCE_TYPE_PK (cr=1 pr=0 pw=0 time=25 us)(object id 823579)
6 SORT JOIN (cr=7 pr=0 pw=0 time=131 us)
6 TABLE ACCESS FULL AE_PROFILE_DETAIL (cr=7 pr=0 pw=0 time=42 us)
201 VIEW (cr=22 pr=0 pw=0 time=7041 us)
201 SORT GROUP BY (cr=22 pr=0 pw=0 time=6838 us)
3000 TABLE ACCESS FULL AE_STATE_TMP (cr=22 pr=0 pw=0 time=31 us)
********************************************************************************
SELECT /* OPT_DYN_SAMP */ /*+ ALL_ROWS IGNORE_WHERE_CLAUSE
NO_PARALLEL(SAMPLESUB) opt_param('parallel_execution_enabled', 'false')
NO_PARALLEL_INDEX(SAMPLESUB) NO_SQL_TUNE */ NVL(SUM(C1),:"SYS_B_0"),
NVL(SUM(C2),:"SYS_B_1")
FROM
(SELECT /*+ NO_PARALLEL("AE_STATE_TMP") FULL("AE_STATE_TMP")
NO_PARALLEL_INDEX("AE_STATE_TMP") */ :"SYS_B_2" AS C1, :"SYS_B_3" AS C2
FROM "AE_STATE_TMP" "AE_STATE_TMP") SAMPLESUB
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 4 0.00 0.00 0 0 0 0
Execute 4 0.00 0.00 0 0 0 0
Fetch 4 0.00 0.00 0 88 0 4
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 12 0.00 0.00 0 88 0 4
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 977 (recursive depth: 2)
Rows Row Source Operation
------- ---------------------------------------------------
1 SORT AGGREGATE (cr=22 pr=0 pw=0 time=645 us)
3000 TABLE ACCESS FULL AE_STATE_TMP (cr=22 pr=0 pw=0 time=61 us)
********************************************************************************
update seq$ set increment$=:2,minvalue=:3,maxvalue=:4,cycle#=:5,order$=:6,
cache=:7,highwater=:8,audit$=:9,flags=:10
where
obj#=:1
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 16 0.00 0.00 0 0 0 0
Execute 16 0.00 0.00 0 32 32 16
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 32 0.00 0.00 0 32 32 16
Misses in library cache during parse: 0
Optimizer mode: CHOOSE
Parsing user id: SYS (recursive depth: 2)
Rows Row Source Operation
------- ---------------------------------------------------
1 UPDATE SEQ$ (cr=2 pr=0 pw=0 time=244 us)
1 INDEX UNIQUE SCAN I_SEQ1 (cr=2 pr=0 pw=0 time=42 us)(object id 102)
********************************************************************************
SELECT /* OPT_DYN_SAMP */ /*+ ALL_ROWS IGNORE_WHERE_CLAUSE
NO_PARALLEL(SAMPLESUB) opt_param('parallel_execution_enabled', 'false')
NO_PARALLEL_INDEX(SAMPLESUB) NO_SQL_TUNE */ NVL(SUM(C1),:"SYS_B_0"),
NVL(SUM(C2),:"SYS_B_1"), COUNT(DISTINCT C3), NVL(SUM(CASE WHEN C3 IS NULL
THEN :"SYS_B_2" ELSE :"SYS_B_3" END),:"SYS_B_4")
FROM
(SELECT /*+ NO_PARALLEL("AE_STATE_TMP") FULL("AE_STATE_TMP")
NO_PARALLEL_INDEX("AE_STATE_TMP") */ :"SYS_B_5" AS C1, :"SYS_B_6" AS C2,
"AE_STATE_TMP"."PROFILE_ID" AS C3 FROM "AE_STATE_TMP" "AE_STATE_TMP")
SAMPLESUB
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 0.00 0.00 0 22 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 3 0.00 0.00 0 22 0 1
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 977 (recursive depth: 2)
Rows Row Source Operation
------- ---------------------------------------------------
1 SORT GROUP BY (cr=22 pr=0 pw=0 time=1572 us)
3000 TABLE ACCESS FULL AE_STATE_TMP (cr=22 pr=0 pw=0 time=26 us)
********************************************************************************
INSERT INTO AE_RESOURCE(ID, DEVICE_ID, OWNER_ID, TYPE_ID, RES_NUM, NAME)
SELECT AE_RESOURCE_SEQ.NEXTVAL, T.DEVICE_ID, O.ID, P.TYPE_ID, T.NUM,
T.VALUE FROM ( SELECT DEVICE_ID, PROFILE_ID, PARAM_ID, NUM , MAX(ID) KEEP
(DENSE_RANK LAST ORDER BY DATETIME) ID , MAX(VALUE) KEEP (DENSE_RANK LAST
ORDER BY DATETIME) VALUE , MAX(DATETIME) DATETIME FROM AE_STATE_TMP GROUP
BY DEVICE_ID, PROFILE_ID, PARAM_ID, NUM ) T INNER JOIN AE_RESOURCE C ON
(C.TMP_ID = T.ID) INNER JOIN AE_PROFILE_DETAIL P ON (P.PROFILE_ID =
T.PROFILE_ID AND P.PARAM_ID = T.PARAM_ID) INNER JOIN AE_RESOURCE_TYPE R ON
(R.ID = P.TYPE_ID) LEFT JOIN AE_RESOURCE O ON (O.DEVICE_ID = T.DEVICE_ID
AND O.TYPE_ID = R.OWNER_ID)
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.01 0.01 0 3 0 0
Execute 1 0.00 0.00 0 24 0 0
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.01 0.02 0 27 0 0
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 977 (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
0 SEQUENCE AE_RESOURCE_SEQ (cr=24 pr=0 pw=0 time=7120 us)
0 NESTED LOOPS OUTER (cr=24 pr=0 pw=0 time=7111 us)
0 VIEW (cr=24 pr=0 pw=0 time=7108 us)
0 NESTED LOOPS (cr=24 pr=0 pw=0 time=7105 us)
0 NESTED LOOPS (cr=24 pr=0 pw=0 time=7104 us)
0 NESTED LOOPS (cr=24 pr=0 pw=0 time=7101 us)
201 VIEW (cr=22 pr=0 pw=0 time=6932 us)
201 SORT GROUP BY (cr=22 pr=0 pw=0 time=6529 us)
3000 TABLE ACCESS FULL AE_STATE_TMP (cr=22 pr=0 pw=0 time=26 us)
0 INDEX RANGE SCAN AE_RES_DEV_RES_TMP_FK (cr=2 pr=0 pw=0 time=465 us)(object id 826402)
0 TABLE ACCESS BY INDEX ROWID AE_PROFILE_DETAIL (cr=0 pr=0 pw=0 time=0 us)
0 INDEX RANGE SCAN AE_PROFILE_DETAIL_PARAM_FK (cr=0 pr=0 pw=0 time=0 us)(object id 824918)
0 TABLE ACCESS BY INDEX ROWID AE_RESOURCE_TYPE (cr=0 pr=0 pw=0 time=0 us)
0 INDEX UNIQUE SCAN AE_RESOURCE_TYPE_PK (cr=0 pr=0 pw=0 time=0 us)(object id 823579)
0 TABLE ACCESS BY INDEX ROWID AE_RESOURCE (cr=0 pr=0 pw=0 time=0 us)
0 INDEX RANGE SCAN AE_RES_DEV_TYPE_FK (cr=0 pr=0 pw=0 time=0 us)(object id 823581)
********************************************************************************
UPDATE AE_RESOURCE SET END_DATE = SYSDATE , TMP_ID = NULL
WHERE
TMP_ID > 0
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 1 0 0
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.00 0.00 0 1 0 0
Misses in library cache during parse: 0
Optimizer mode: ALL_ROWS
Parsing user id: 977 (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
0 UPDATE AE_RESOURCE (cr=1 pr=0 pw=0 time=31 us)
0 INDEX RANGE SCAN AE_RES_DEV_RES_TMP_FK (cr=1 pr=0 pw=0 time=16 us)(object id 826402)
********************************************************************************
INSERT INTO AE_STATE_LOG(ID, RES_ID, PARAM_ID, VALUE) SELECT
AE_STATE_LOG_SEQ.NEXTVAL, ID, PARAM_ID, VALUE FROM ( SELECT DISTINCT R.ID,
T.PARAM_ID, DECODE(L.TYPE_ID, :B6 , NVL(S.VALUE, T.VALUE), T.VALUE) VALUE
FROM ( SELECT DEVICE_ID, PROFILE_ID, PARAM_ID, NUM , MAX(ID) KEEP
(DENSE_RANK LAST ORDER BY DATETIME) ID , MAX(VALUE) KEEP (DENSE_RANK LAST
ORDER BY DATETIME) VALUE , MAX(DATETIME) DATETIME FROM AE_STATE_TMP GROUP
BY DEVICE_ID, PROFILE_ID, PARAM_ID, NUM ) T INNER JOIN AE_PROFILE_DETAIL P
ON (P.PROFILE_ID = T.PROFILE_ID AND P.PARAM_ID = T.PARAM_ID) INNER JOIN
AE_RESOURCE R ON ( R.DEVICE_ID = T.DEVICE_ID AND R.RES_NUM = T.NUM AND
R.TYPE_ID = P.TYPE_ID AND R.START_DATE <= SYSDATE AND SYSDATE <=
NVL(R.END_DATE, SYSDATE + 1)) LEFT JOIN AE_STATE S ON (S.RES_ID = R.ID AND
S.PARAM_ID = T.PARAM_ID) INNER JOIN AE_PARAMETER A ON (A.ID = P.PARAM_ID)
INNER JOIN AE_DOMAIN D ON (D.ID = A.DOMAIN_ID) INNER JOIN AE_STATE_POLICY L
ON (L.ID = D.POLICY_ID) LEFT JOIN AE_THRESHOLD H ON ( H.POLICY_ID = L.ID
AND (( H.TYPE_ID = :B3 AND S.VALUE <= H.VALUE AND T.VALUE >= H.VALUE ) OR (
H.TYPE_ID = :B2 AND S.VALUE >= H.VALUE AND T.VALUE <= H.VALUE ) OR (
H.TYPE_ID = :B1 AND ABS(T.VALUE - S.VALUE) >= H.VALUE ))) WHERE ( S.ID IS
NULL OR NOT H.ID IS NULL OR ( L.TYPE_ID = :B6 AND T.VALUE < S.VALUE ) OR (
L.TYPE_ID = :B5 AND T.VALUE <> S.VALUE ) ) AND T.PARAM_ID <> :B4 )
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.34 0.33 3 48582 41 101
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.34 0.33 3 48582 41 101
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 977 (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
101 SEQUENCE AE_STATE_LOG_SEQ (cr=48555 pr=0 pw=0 time=382497 us)
101 VIEW (cr=48545 pr=0 pw=0 time=301374 us)
101 SORT UNIQUE (cr=48545 pr=0 pw=0 time=301170 us)
101 FILTER (cr=48545 pr=0 pw=0 time=305839 us)
101 NESTED LOOPS OUTER (cr=48545 pr=0 pw=0 time=305636 us)
101 NESTED LOOPS (cr=48443 pr=0 pw=0 time=301913 us)
101 NESTED LOOPS (cr=48340 pr=0 pw=0 time=300190 us)
101 NESTED LOOPS (cr=48237 pr=0 pw=0 time=298864 us)
101 NESTED LOOPS OUTER (cr=48134 pr=0 pw=0 time=297528 us)
101 VIEW (cr=48031 pr=0 pw=0 time=295688 us)
101 SORT GROUP BY (cr=48031 pr=0 pw=0 time=295586 us)
2000 TABLE ACCESS BY INDEX ROWID AE_RESOURCE (cr=48031 pr=0 pw=0 time=272207 us)
103001 NESTED LOOPS (cr=46031 pr=0 pw=0 time=206642 us)
2000 HASH JOIN (cr=29 pr=0 pw=0 time=8271 us)
5 TABLE ACCESS FULL AE_PROFILE_DETAIL (cr=7 pr=0 pw=0 time=43 us)
2000 TABLE ACCESS FULL AE_STATE_TMP (cr=22 pr=0 pw=0 time=2035 us)
101000 INDEX RANGE SCAN AE_RES_DEV_TYPE_FK (cr=46002 pr=0 pw=0 time=68456 us)(object id 823581)
0 TABLE ACCESS BY INDEX ROWID AE_STATE (cr=103 pr=0 pw=0 time=894 us)
0 INDEX RANGE SCAN AE_STATE_RES_FK (cr=103 pr=0 pw=0 time=644 us)(object id 813807)
101 TABLE ACCESS BY INDEX ROWID AE_PARAMETER (cr=103 pr=0 pw=0 time=918 us)
101 INDEX UNIQUE SCAN AE_PARAMETER_PK (cr=2 pr=0 pw=0 time=340 us)(object id 812977)
101 TABLE ACCESS BY INDEX ROWID AE_DOMAIN (cr=103 pr=0 pw=0 time=767 us)
101 INDEX UNIQUE SCAN AE_DOMAIN_PK (cr=2 pr=0 pw=0 time=302 us)(object id 814562)
101 TABLE ACCESS BY INDEX ROWID AE_STATE_POLICY (cr=103 pr=0 pw=0 time=776 us)
101 INDEX UNIQUE SCAN AE_STATE_POLICY_PK (cr=2 pr=0 pw=0 time=312 us)(object id 826206)
0 VIEW (cr=102 pr=0 pw=0 time=1369 us)
0 TABLE ACCESS BY INDEX ROWID AE_THRESHOLD (cr=102 pr=0 pw=0 time=1131 us)
100 INDEX RANGE SCAN AE_THRESHOLD_PROFILE_FK (cr=2 pr=0 pw=0 time=436 us)(object id 825819)
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
db file sequential read 3 0.00 0.00
********************************************************************************
SELECT /* OPT_DYN_SAMP */ /*+ ALL_ROWS IGNORE_WHERE_CLAUSE
NO_PARALLEL(SAMPLESUB) opt_param('parallel_execution_enabled', 'false')
NO_PARALLEL_INDEX(SAMPLESUB) NO_SQL_TUNE */ NVL(SUM(C1),0), NVL(SUM(C2),0),
COUNT(DISTINCT C3), NVL(SUM(CASE WHEN C3 IS NULL THEN 1 ELSE 0 END),0)
FROM
(SELECT /*+ IGNORE_WHERE_CLAUSE NO_PARALLEL("AE_STATE_TMP")
FULL("AE_STATE_TMP") NO_PARALLEL_INDEX("AE_STATE_TMP") */ 1 AS C1, CASE
WHEN "AE_STATE_TMP"."PARAM_ID"<>:B1 THEN 1 ELSE 0 END AS C2,
"AE_STATE_TMP"."DEVICE_ID" AS C3 FROM "AE_STATE_TMP" "AE_STATE_TMP")
SAMPLESUB
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 0.00 0.00 0 22 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 3 0.00 0.00 0 22 0 1
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 977 (recursive depth: 2)
Rows Row Source Operation
------- ---------------------------------------------------
1 SORT GROUP BY (cr=22 pr=0 pw=0 time=2089 us)
3000 TABLE ACCESS FULL AE_STATE_TMP (cr=22 pr=0 pw=0 time=27 us)
********************************************************************************
MERGE INTO AE_STATE D USING ( SELECT T.PARAM_ID, T.VALUE, R.ID RES_ID FROM (
SELECT DEVICE_ID, PROFILE_ID, PARAM_ID, NUM , MAX(ID) KEEP (DENSE_RANK LAST
ORDER BY DATETIME) ID , MAX(VALUE) KEEP (DENSE_RANK LAST ORDER BY DATETIME)
VALUE , MAX(DATETIME) DATETIME FROM AE_STATE_TMP GROUP BY DEVICE_ID,
PROFILE_ID, PARAM_ID, NUM ) T INNER JOIN AE_PROFILE_DETAIL P ON
(P.PROFILE_ID = T.PROFILE_ID AND P.PARAM_ID = T.PARAM_ID) INNER JOIN
AE_RESOURCE R ON ( R.DEVICE_ID = T.DEVICE_ID AND R.RES_NUM = T.NUM AND
R.TYPE_ID = P.TYPE_ID AND R.START_DATE <= SYSDATE AND SYSDATE <=
NVL(R.END_DATE, SYSDATE + 1)) WHERE T.PARAM_ID <> :B1 ) S ON (D.RES_ID =
S.RES_ID AND D.PARAM_ID = S.PARAM_ID) WHEN MATCHED THEN UPDATE SET D.VALUE =
S.VALUE , D.DATETIME = CURRENT_TIMESTAMP WHEN NOT MATCHED THEN INSERT (ID,
PARAM_ID, RES_ID, VALUE) VALUES (AE_STATE_SEQ.NEXTVAL, S.PARAM_ID, S.RES_ID,
S.VALUE)
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.02 0.01 0 108 1020 101
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.02 0.01 0 108 1020 101
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 977 (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
2 MERGE AE_STATE (cr=148 pr=0 pw=0 time=18039 us)
101 VIEW (cr=147 pr=0 pw=0 time=8324 us)
101 SEQUENCE AE_STATE_SEQ (cr=147 pr=0 pw=0 time=8222 us)
101 HASH JOIN RIGHT OUTER (cr=137 pr=0 pw=0 time=7595 us)
0 TABLE ACCESS FULL AE_STATE (cr=61 pr=0 pw=0 time=664 us)
101 VIEW (cr=76 pr=0 pw=0 time=6546 us)
101 HASH JOIN (cr=76 pr=0 pw=0 time=6343 us)
302 MERGE JOIN (cr=54 pr=0 pw=0 time=994 us)
101 TABLE ACCESS BY INDEX ROWID AE_RESOURCE (cr=47 pr=0 pw=0 time=8927 us)
101 INDEX FULL SCAN AE_RES_DEV_TYPE_FK (cr=45 pr=0 pw=0 time=8315 us)(object id 823581)
302 SORT JOIN (cr=7 pr=0 pw=0 time=233 us)
5 TABLE ACCESS FULL AE_PROFILE_DETAIL (cr=7 pr=0 pw=0 time=27 us)
101 VIEW (cr=22 pr=0 pw=0 time=4651 us)
101 SORT GROUP BY (cr=22 pr=0 pw=0 time=4547 us)
2000 TABLE ACCESS FULL AE_STATE_TMP (cr=22 pr=0 pw=0 time=23 us)
********************************************************************************
SELECT /* OPT_DYN_SAMP */ /*+ ALL_ROWS IGNORE_WHERE_CLAUSE
NO_PARALLEL(SAMPLESUB) opt_param('parallel_execution_enabled', 'false')
NO_PARALLEL_INDEX(SAMPLESUB) NO_SQL_TUNE */ NVL(SUM(C1),0), NVL(SUM(C2),0)
FROM
(SELECT /*+ IGNORE_WHERE_CLAUSE NO_PARALLEL("AE_STATE_TMP")
FULL("AE_STATE_TMP") NO_PARALLEL_INDEX("AE_STATE_TMP") */ 1 AS C1, CASE
WHEN "AE_STATE_TMP"."PARAM_ID"<>:B1 THEN 1 ELSE 0 END AS C2 FROM
"AE_STATE_TMP" "AE_STATE_TMP") SAMPLESUB
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 2 0.00 0.00 0 0 0 0
Execute 2 0.00 0.00 0 0 0 0
Fetch 2 0.00 0.00 0 44 0 2
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 6 0.00 0.00 0 44 0 2
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 977 (recursive depth: 2)
Rows Row Source Operation
------- ---------------------------------------------------
1 SORT AGGREGATE (cr=22 pr=0 pw=0 time=1087 us)
3000 TABLE ACCESS FULL AE_STATE_TMP (cr=22 pr=0 pw=0 time=30 us)
********************************************************************************
COMMIT WRITE NOWAIT
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 1 0
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.00 0.00 0 0 1 0
Misses in library cache during parse: 0
Parsing user id: 977 (recursive depth: 1)
********************************************************************************
OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 2 0.00 0.00 0 0 0 0
Execute 1001 0.36 0.33 0 96 6616 3001
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 1003 0.36 0.33 0 96 6616 3001
Misses in library cache during parse: 2
Misses in library cache during execute: 1
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 1002 0.00 0.00
SQL*Net message from client 1002 0.00 0.41
log file sync 1 0.00 0.00
OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 30 0.01 0.01 0 3 0 0
Execute 30 0.41 0.40 3 48932 1104 218
Fetch 8 0.00 0.00 0 176 0 8
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 68 0.44 0.43 3 49111 1104 226
Misses in library cache during parse: 8
Misses in library cache during execute: 7
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
db file sequential read 3 0.00 0.00
16 user SQL statements in session.
16 internal SQL statements in session.
32 SQL statements in session.
********************************************************************************
Trace file: distinct.trc
Trace file compatibility: 10.01.00
Sort options: default
1 session in tracefile.
16 user SQL statements in trace file.
16 internal SQL statements in trace file.
32 SQL statements in trace file.
13 unique SQL statements in trace file.
36390 lines in trace file.
1 elapsed seconds in trace file.
bulk
TKPROF: Release 10.2.0.3.0 - Production on Wed Oct 23 12:08:03 2013
Copyright (c) 1982, 2005, Oracle. All rights reserved.
Trace file: bulk.trc
Sort options: default
********************************************************************************
count = number of times OCI procedure was executed
cpu = cpu time in seconds executing
elapsed = elapsed time in seconds executing
disk = number of physical reads of buffers from disk
query = number of buffers gotten for consistent read
current = number of buffers gotten in current mode (usually for update)
rows = number of rows processed by the fetch or execute call
********************************************************************************
begin :1 := dbms_pickler.get_type_shape(:2,:3,:4,:5,:6,:7); :8 :=
dbms_pickler.get_format(:9); end;
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 8 0 1
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.00 0.00 0 8 0 1
Misses in library cache during parse: 0
Optimizer mode: ALL_ROWS
Parsing user id: 977
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 1 0.00 0.00
SQL*Net message from client 1 0.01 0.01
********************************************************************************
select metadata
from
kopm$ where name='DB_FDO'
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 0.00 0.00 0 2 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 3 0.00 0.00 0 2 0 1
Misses in library cache during parse: 0
Optimizer mode: CHOOSE
Parsing user id: SYS (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
1 TABLE ACCESS BY INDEX ROWID KOPM$ (cr=2 pr=0 pw=0 time=53 us)
1 INDEX UNIQUE SCAN I_KOPM1 (cr=1 pr=0 pw=0 time=25 us)(object id 365)
********************************************************************************
begin :1 := dbms_pickler.get_type_shape(:2,:3,:4,:5,:6,:7); end;
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 3 0 1
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.00 0.00 0 3 0 1
Misses in library cache during parse: 0
Optimizer mode: ALL_ROWS
Parsing user id: 977
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 1 0.00 0.00
SQL*Net message from client 1 0.00 0.00
********************************************************************************
SELECT INSTANTIABLE, supertype_owner, supertype_name, LOCAL_ATTRIBUTES
FROM
all_types WHERE type_name = :1 AND owner = :2
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 0.00 0.00 0 9 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 3 0.00 0.00 0 9 0 1
Misses in library cache during parse: 0
Optimizer mode: ALL_ROWS
Parsing user id: 977
Rows Row Source Operation
------- ---------------------------------------------------
1 VIEW ALL_TYPES (cr=9 pr=0 pw=0 time=358 us)
1 SORT UNIQUE (cr=9 pr=0 pw=0 time=356 us)
1 UNION-ALL (cr=9 pr=0 pw=0 time=299 us)
1 FILTER (cr=9 pr=0 pw=0 time=272 us)
1 NESTED LOOPS OUTER (cr=9 pr=0 pw=0 time=260 us)
1 NESTED LOOPS OUTER (cr=9 pr=0 pw=0 time=247 us)
1 NESTED LOOPS (cr=9 pr=0 pw=0 time=237 us)
1 NESTED LOOPS (cr=6 pr=0 pw=0 time=166 us)
1 TABLE ACCESS BY INDEX ROWID USER$ (cr=2 pr=0 pw=0 time=56 us)
1 INDEX UNIQUE SCAN I_USER1 (cr=1 pr=0 pw=0 time=34 us)(object id 44)
1 TABLE ACCESS BY INDEX ROWID OBJ$ (cr=4 pr=0 pw=0 time=106 us)
1 INDEX RANGE SCAN I_OBJ2 (cr=3 pr=0 pw=0 time=67 us)(object id 37)
1 TABLE ACCESS BY INDEX ROWID TYPE$ (cr=3 pr=0 pw=0 time=68 us)
1 INDEX UNIQUE SCAN I_TYPE2 (cr=2 pr=0 pw=0 time=40 us)(object id 185)
0 TABLE ACCESS BY INDEX ROWID OBJ$ (cr=0 pr=0 pw=0 time=5 us)
0 INDEX RANGE SCAN I_OBJ3 (cr=0 pr=0 pw=0 time=1 us)(object id 38)
0 TABLE ACCESS CLUSTER USER$ (cr=0 pr=0 pw=0 time=6 us)
0 INDEX UNIQUE SCAN I_USER# (cr=0 pr=0 pw=0 time=2 us)(object id 11)
0 NESTED LOOPS (cr=0 pr=0 pw=0 time=0 us)
0 INDEX RANGE SCAN I_OBJAUTH1 (cr=0 pr=0 pw=0 time=0 us)(object id 103)
0 FIXED TABLE FULL X$KZSRO (cr=0 pr=0 pw=0 time=0 us)
0 FIXED TABLE FULL X$KZSPR (cr=0 pr=0 pw=0 time=0 us)
0 FILTER (cr=0 pr=0 pw=0 time=5 us)
0 FILTER (cr=0 pr=0 pw=0 time=2 us)
0 NESTED LOOPS OUTER (cr=0 pr=0 pw=0 time=0 us)
0 NESTED LOOPS OUTER (cr=0 pr=0 pw=0 time=0 us)
0 MERGE JOIN CARTESIAN (cr=0 pr=0 pw=0 time=0 us)
0 NESTED LOOPS (cr=0 pr=0 pw=0 time=0 us)
0 TABLE ACCESS BY INDEX ROWID OBJ$ (cr=0 pr=0 pw=0 time=0 us)
0 INDEX SKIP SCAN I_OBJ2 (cr=0 pr=0 pw=0 time=0 us)(object id 37)
0 TABLE ACCESS BY INDEX ROWID TYPE$ (cr=0 pr=0 pw=0 time=0 us)
0 INDEX UNIQUE SCAN I_TYPE2 (cr=0 pr=0 pw=0 time=0 us)(object id 185)
0 BUFFER SORT (cr=0 pr=0 pw=0 time=0 us)
0 INDEX FULL SCAN I_USER1 (cr=0 pr=0 pw=0 time=0 us)(object id 44)
0 TABLE ACCESS BY INDEX ROWID OBJ$ (cr=0 pr=0 pw=0 time=0 us)
0 INDEX RANGE SCAN I_OBJ3 (cr=0 pr=0 pw=0 time=0 us)(object id 38)
0 TABLE ACCESS CLUSTER USER$ (cr=0 pr=0 pw=0 time=0 us)
0 INDEX UNIQUE SCAN I_USER# (cr=0 pr=0 pw=0 time=0 us)(object id 11)
0 NESTED LOOPS (cr=0 pr=0 pw=0 time=0 us)
0 INDEX RANGE SCAN I_OBJAUTH1 (cr=0 pr=0 pw=0 time=0 us)(object id 103)
0 FIXED TABLE FULL X$KZSRO (cr=0 pr=0 pw=0 time=0 us)
0 FIXED TABLE FULL X$KZSPR (cr=0 pr=0 pw=0 time=0 us)
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 2 0.00 0.00
SQL*Net message from client 2 0.06 0.06
********************************************************************************
begin ae_monitoring.saveValues(:1); end;
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.20 0.20 4 685 1095 1
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.20 0.20 4 685 1095 1
Misses in library cache during parse: 0
Optimizer mode: ALL_ROWS
Parsing user id: 977
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net more data from client 41 0.00 0.00
SQL*Net message to client 1 0.00 0.00
SQL*Net message from client 1 0.00 0.00
********************************************************************************
MERGE INTO AE_RESOURCE D USING ( SELECT T.DEVICE_ID, T.NUM, DECODE(O.ID, NULL,
T.NUM, T.VALUE) NAME, P.TYPE_ID, O.ID OWNER_ID FROM ( SELECT DEVICE_ID,
PROFILE_ID, PARAM_ID, NUM , MAX(VALUE) VALUE FROM TABLE( :B1 ) GROUP BY
DEVICE_ID, PROFILE_ID, PARAM_ID, NUM ) T INNER JOIN AE_PROFILE_DETAIL P ON
(P.PROFILE_ID = T.PROFILE_ID AND P.PARAM_ID = T.PARAM_ID) INNER JOIN
AE_RESOURCE_TYPE R ON (R.ID = P.TYPE_ID) LEFT JOIN AE_RESOURCE O ON
(O.DEVICE_ID = T.DEVICE_ID AND O.TYPE_ID = R.OWNER_ID) WHERE T.PARAM_ID =
:B2 OR O.ID IS NULL ) S ON ( D.DEVICE_ID = S.DEVICE_ID AND D.RES_NUM =
S.NUM AND D.TYPE_ID = S.TYPE_ID AND D.START_DATE <= SYSDATE AND SYSDATE <=
NVL(D.END_DATE, SYSDATE + 1) ) WHEN NOT MATCHED THEN INSERT (ID, DEVICE_ID,
OWNER_ID, TYPE_ID, RES_NUM, NAME) VALUES (AE_RESOURCE_SEQ.NEXTVAL,
S.DEVICE_ID, S.OWNER_ID, S.TYPE_ID, S.NUM, S.NAME)
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.03 0.02 0 161 5 0
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.03 0.02 0 161 5 0
Misses in library cache during parse: 0
Optimizer mode: ALL_ROWS
Parsing user id: 977 (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
1 MERGE AE_RESOURCE (cr=171 pr=0 pw=0 time=21318 us)
101 VIEW (cr=171 pr=0 pw=0 time=18571 us)
101 SEQUENCE AE_RESOURCE_SEQ (cr=171 pr=0 pw=0 time=17567 us)
101 FILTER (cr=161 pr=0 pw=0 time=17203 us)
201 HASH JOIN RIGHT OUTER (cr=161 pr=0 pw=0 time=18200 us)
101 TABLE ACCESS FULL AE_RESOURCE (cr=76 pr=0 pw=0 time=46040 us)
201 HASH JOIN RIGHT OUTER (cr=85 pr=0 pw=0 time=15548 us)
101 TABLE ACCESS FULL AE_RESOURCE (cr=76 pr=0 pw=0 time=10066 us)
201 VIEW (cr=9 pr=0 pw=0 time=12926 us)
201 HASH JOIN (cr=9 pr=0 pw=0 time=12723 us)
6 MERGE JOIN (cr=9 pr=0 pw=0 time=227 us)
2 TABLE ACCESS BY INDEX ROWID AE_RESOURCE_TYPE (cr=2 pr=0 pw=0 time=68 us)
2 INDEX FULL SCAN AE_RESOURCE_TYPE_PK (cr=1 pr=0 pw=0 time=40 us)(object id 823579)
6 SORT JOIN (cr=7 pr=0 pw=0 time=153 us)
6 TABLE ACCESS FULL AE_PROFILE_DETAIL (cr=7 pr=0 pw=0 time=50 us)
201 VIEW (cr=0 pr=0 pw=0 time=10984 us)
201 SORT GROUP BY (cr=0 pr=0 pw=0 time=10982 us)
3000 COLLECTION ITERATOR PICKLER FETCH (cr=0 pr=0 pw=0 time=25 us)
********************************************************************************
update seq$ set increment$=:2,minvalue=:3,maxvalue=:4,cycle#=:5,order$=:6,
cache=:7,highwater=:8,audit$=:9,flags=:10
where
obj#=:1
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 15 0.00 0.00 0 0 0 0
Execute 15 0.00 0.00 0 30 31 15
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 30 0.00 0.00 0 30 31 15
Misses in library cache during parse: 0
Optimizer mode: CHOOSE
Parsing user id: SYS (recursive depth: 2)
Rows Row Source Operation
------- ---------------------------------------------------
1 UPDATE SEQ$ (cr=2 pr=0 pw=0 time=412 us)
1 INDEX UNIQUE SCAN I_SEQ1 (cr=2 pr=0 pw=0 time=34 us)(object id 102)
********************************************************************************
INSERT INTO AE_STATE_LOG(ID, RES_ID, PARAM_ID, VALUE) SELECT
AE_STATE_LOG_SEQ.NEXTVAL, ID, PARAM_ID, VALUE FROM ( SELECT DISTINCT R.ID,
T.PARAM_ID, DECODE(L.TYPE_ID, :B7 , NVL(S.VALUE, T.VALUE), T.VALUE) VALUE
FROM ( SELECT DEVICE_ID, PROFILE_ID, PARAM_ID, NUM , MAX(VALUE) VALUE FROM
TABLE( :B1 ) GROUP BY DEVICE_ID, PROFILE_ID, PARAM_ID, NUM ) T INNER JOIN
AE_PROFILE_DETAIL P ON (P.PROFILE_ID = T.PROFILE_ID AND P.PARAM_ID =
T.PARAM_ID) INNER JOIN AE_RESOURCE R ON ( R.DEVICE_ID = T.DEVICE_ID AND
R.RES_NUM = T.NUM AND R.TYPE_ID = P.TYPE_ID AND R.START_DATE <= SYSDATE AND
SYSDATE <= NVL(R.END_DATE, SYSDATE + 1)) LEFT JOIN AE_STATE S ON (S.RES_ID =
R.ID AND S.PARAM_ID = T.PARAM_ID) INNER JOIN AE_PARAMETER A ON (A.ID =
P.PARAM_ID) INNER JOIN AE_DOMAIN D ON (D.ID = A.DOMAIN_ID) INNER JOIN
AE_STATE_POLICY L ON (L.ID = D.POLICY_ID) LEFT JOIN AE_THRESHOLD H ON (
H.POLICY_ID = L.ID AND (( H.TYPE_ID = :B4 AND S.VALUE <= H.VALUE AND
T.VALUE >= H.VALUE ) OR ( H.TYPE_ID = :B3 AND S.VALUE >= H.VALUE AND
T.VALUE <= H.VALUE ) OR ( H.TYPE_ID = :B2 AND ABS(T.VALUE - S.VALUE) >=
H.VALUE ))) WHERE ( S.ID IS NULL OR NOT H.ID IS NULL OR ( L.TYPE_ID = :B7
AND T.VALUE < S.VALUE ) OR ( L.TYPE_ID = :B6 AND T.VALUE <> S.VALUE ) ) AND
T.PARAM_ID <> :B5 )
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.12 0.11 3 388 42 101
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.12 0.11 3 388 42 101
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 977 (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
101 SEQUENCE AE_STATE_LOG_SEQ (cr=203 pr=0 pw=0 time=25270 us)
101 VIEW (cr=193 pr=0 pw=0 time=24741 us)
101 SORT UNIQUE (cr=193 pr=0 pw=0 time=24539 us)
101 FILTER (cr=193 pr=0 pw=0 time=24683 us)
101 NESTED LOOPS OUTER (cr=193 pr=0 pw=0 time=24579 us)
101 HASH JOIN OUTER (cr=91 pr=0 pw=0 time=22733 us)
101 HASH JOIN (cr=70 pr=0 pw=0 time=22407 us)
5 HASH JOIN (cr=16 pr=0 pw=0 time=1754 us)
5 TABLE ACCESS BY INDEX ROWID AE_DOMAIN (cr=9 pr=0 pw=0 time=1077 us)
8 NESTED LOOPS (cr=8 pr=0 pw=0 time=7064 us)
2 VIEW index$_join$_015 (cr=6 pr=0 pw=0 time=997 us)
2 HASH JOIN (cr=6 pr=0 pw=0 time=993 us)
2 INDEX FAST FULL SCAN AE_STATE_POLICY_FK (cr=3 pr=0 pw=0 time=93 us)(object id 826212)
2 INDEX FAST FULL SCAN AE_STATE_POLICY_PK (cr=3 pr=0 pw=0 time=51 us)(object id 826206)
5 INDEX RANGE SCAN AE_DOMAIN_FK (cr=2 pr=0 pw=0 time=26 us)(object id 826208)
57 TABLE ACCESS FULL AE_PARAMETER (cr=7 pr=0 pw=0 time=117 us)
101 VIEW (cr=54 pr=0 pw=0 time=19997 us)
101 SORT GROUP BY (cr=54 pr=0 pw=0 time=19893 us)
2000 HASH JOIN (cr=54 pr=0 pw=0 time=14354 us)
302 MERGE JOIN (cr=54 pr=0 pw=0 time=1023 us)
101 TABLE ACCESS BY INDEX ROWID AE_RESOURCE (cr=47 pr=0 pw=0 time=36446 us)
101 INDEX FULL SCAN AE_RES_DEV_TYPE_FK (cr=45 pr=0 pw=0 time=35634 us)(object id 823581)
302 SORT JOIN (cr=7 pr=0 pw=0 time=255 us)
5 TABLE ACCESS FULL AE_PROFILE_DETAIL (cr=7 pr=0 pw=0 time=30 us)
2000 COLLECTION ITERATOR PICKLER FETCH (cr=0 pr=0 pw=0 time=2015 us)
0 TABLE ACCESS BY INDEX ROWID AE_STATE (cr=21 pr=0 pw=0 time=252 us)
0 BITMAP CONVERSION TO ROWIDS (cr=21 pr=0 pw=0 time=248 us)
0 BITMAP MINUS (cr=21 pr=0 pw=0 time=234 us)
0 BITMAP CONVERSION FROM ROWIDS (cr=21 pr=0 pw=0 time=224 us)
0 SORT ORDER BY (cr=21 pr=0 pw=0 time=221 us)
0 INDEX FULL SCAN AE_STATE_PK (cr=21 pr=0 pw=0 time=207 us)(object id 813023)
0 BITMAP CONVERSION FROM ROWIDS (cr=0 pr=0 pw=0 time=3 us)
0 INDEX RANGE SCAN AE_STATE_PARAM_FK (cr=0 pr=0 pw=0 time=3 us)(object id 813025)
0 VIEW (cr=102 pr=0 pw=0 time=1419 us)
0 TABLE ACCESS BY INDEX ROWID AE_THRESHOLD (cr=102 pr=0 pw=0 time=1201 us)
100 INDEX RANGE SCAN AE_THRESHOLD_PROFILE_FK (cr=2 pr=0 pw=0 time=467 us)(object id 825819)
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
db file sequential read 3 0.00 0.00
********************************************************************************
select obj#,type#,ctime,mtime,stime,status,dataobj#,flags,oid$, spare1,
spare2
from
obj$ where owner#=:1 and name=:2 and namespace=:3 and remoteowner is null
and linkname is null and subname is null
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 0.00 0.00 0 4 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 3 0.00 0.00 0 4 0 1
Misses in library cache during parse: 0
Optimizer mode: CHOOSE
Parsing user id: SYS (recursive depth: 2)
Rows Row Source Operation
------- ---------------------------------------------------
1 TABLE ACCESS BY INDEX ROWID OBJ$ (cr=4 pr=0 pw=0 time=50 us)
1 INDEX RANGE SCAN I_OBJ2 (cr=3 pr=0 pw=0 time=29 us)(object id 37)
********************************************************************************
select t.ts#,t.file#,t.block#,nvl(t.bobj#,0),nvl(t.tab#,0),t.intcols,
nvl(t.clucols,0),t.audit$,t.flags,t.pctfree$,t.pctused$,t.initrans,
t.maxtrans,t.rowcnt,t.blkcnt,t.empcnt,t.avgspc,t.chncnt,t.avgrln,
t.analyzetime,t.samplesize,t.cols,t.property,nvl(t.degree,1),
nvl(t.instances,1),t.avgspc_flb,t.flbcnt,t.kernelcols,nvl(t.trigflag, 0),
nvl(t.spare1,0),nvl(t.spare2,0),t.spare4,t.spare6,ts.cachedblk,ts.cachehit,
ts.logicalread
from
tab$ t, tab_stats$ ts where t.obj#= :1 and t.obj# = ts.obj# (+)
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 0.00 0.00 0 4 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 3 0.00 0.00 0 4 0 1
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: CHOOSE
Parsing user id: SYS (recursive depth: 2)
Rows Row Source Operation
------- ---------------------------------------------------
1 NESTED LOOPS OUTER (cr=4 pr=0 pw=0 time=89 us)
1 TABLE ACCESS CLUSTER TAB$ (cr=3 pr=0 pw=0 time=69 us)
1 INDEX UNIQUE SCAN I_OBJ# (cr=2 pr=0 pw=0 time=32 us)(object id 3)
0 TABLE ACCESS BY INDEX ROWID TAB_STATS$ (cr=1 pr=0 pw=0 time=15 us)
0 INDEX UNIQUE SCAN I_TAB_STATS$_OBJ# (cr=1 pr=0 pw=0 time=12 us)(object id 709)
********************************************************************************
select i.obj#,i.ts#,i.file#,i.block#,i.intcols,i.type#,i.flags,i.property,
i.pctfree$,i.initrans,i.maxtrans,i.blevel,i.leafcnt,i.distkey,i.lblkkey,
i.dblkkey,i.clufac,i.cols,i.analyzetime,i.samplesize,i.dataobj#,
nvl(i.degree,1),nvl(i.instances,1),i.rowcnt,mod(i.pctthres$,256),
i.indmethod#,i.trunccnt,nvl(c.unicols,0),nvl(c.deferrable#+c.valid#,0),
nvl(i.spare1,i.intcols),i.spare4,i.spare2,i.spare6,decode(i.pctthres$,null,
null,mod(trunc(i.pctthres$/256),256)),ist.cachedblk,ist.cachehit,
ist.logicalread
from
ind$ i, ind_stats$ ist, (select enabled, min(cols) unicols,
min(to_number(bitand(defer,1))) deferrable#,min(to_number(bitand(defer,4)))
valid# from cdef$ where obj#=:1 and enabled > 1 group by enabled) c where
i.obj#=c.enabled(+) and i.obj# = ist.obj#(+) and i.bo#=:1 order by i.obj#
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 4 0.00 0.00 0 13 0 3
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 6 0.00 0.00 0 13 0 3
Misses in library cache during parse: 0
Optimizer mode: CHOOSE
Parsing user id: SYS (recursive depth: 2)
Rows Row Source Operation
------- ---------------------------------------------------
3 SORT ORDER BY (cr=13 pr=0 pw=0 time=454 us)
3 HASH JOIN OUTER (cr=13 pr=0 pw=0 time=414 us)
3 NESTED LOOPS OUTER (cr=8 pr=0 pw=0 time=69 us)
3 TABLE ACCESS CLUSTER IND$ (cr=6 pr=0 pw=0 time=38 us)
1 INDEX UNIQUE SCAN I_OBJ# (cr=2 pr=0 pw=0 time=9 us)(object id 3)
0 TABLE ACCESS BY INDEX ROWID IND_STATS$ (cr=2 pr=0 pw=0 time=25 us)
0 INDEX UNIQUE SCAN I_IND_STATS$_OBJ# (cr=2 pr=0 pw=0 time=18 us)(object id 711)
1 VIEW (cr=5 pr=0 pw=0 time=130 us)
1 SORT GROUP BY (cr=5 pr=0 pw=0 time=127 us)
1 TABLE ACCESS CLUSTER CDEF$ (cr=5 pr=0 pw=0 time=86 us)
1 INDEX UNIQUE SCAN I_COBJ# (cr=2 pr=0 pw=0 time=30 us)(object id 30)
********************************************************************************
select pos#,intcol#,col#,spare1,bo#,spare2
from
icol$ where obj#=:1
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 3 0.00 0.00 0 0 0 0
Fetch 6 0.00 0.00 0 12 0 3
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 10 0.00 0.00 0 12 0 3
Misses in library cache during parse: 0
Optimizer mode: CHOOSE
Parsing user id: SYS (recursive depth: 2)
Rows Row Source Operation
------- ---------------------------------------------------
1 TABLE ACCESS BY INDEX ROWID ICOL$ (cr=4 pr=0 pw=0 time=44 us)
1 INDEX RANGE SCAN I_ICOL1 (cr=3 pr=0 pw=0 time=42 us)(object id 40)
********************************************************************************
select name,intcol#,segcol#,type#,length,nvl(precision#,0),decode(type#,2,
nvl(scale,-127/*MAXSB1MINAL*/),178,scale,179,scale,180,scale,181,scale,182,
scale,183,scale,231,scale,0),null$,fixedstorage,nvl(deflength,0),default$,
rowid,col#,property, nvl(charsetid,0),nvl(charsetform,0),spare1,spare2,
nvl(spare3,0)
from
col$ where obj#=:1 order by intcol#
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 6 0.00 0.00 0 4 0 5
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 8 0.00 0.00 0 4 0 5
Misses in library cache during parse: 0
Optimizer mode: CHOOSE
Parsing user id: SYS (recursive depth: 2)
Rows Row Source Operation
------- ---------------------------------------------------
5 SORT ORDER BY (cr=3 pr=0 pw=0 time=56 us)
5 TABLE ACCESS CLUSTER COL$ (cr=3 pr=0 pw=0 time=24 us)
1 INDEX UNIQUE SCAN I_OBJ# (cr=2 pr=0 pw=0 time=13 us)(object id 3)
********************************************************************************
select con#,obj#,rcon#,enabled,nvl(defer,0)
from
cdef$ where robj#=:1
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 3 0.00 0.00 0 6 0 2
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 5 0.00 0.00 0 6 0 2
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: CHOOSE
Parsing user id: SYS (recursive depth: 2)
Rows Row Source Operation
------- ---------------------------------------------------
2 TABLE ACCESS BY INDEX ROWID CDEF$ (cr=6 pr=0 pw=0 time=48 us)
2 INDEX RANGE SCAN I_CDEF3 (cr=4 pr=0 pw=0 time=36 us)(object id 52)
********************************************************************************
select con#,type#,condlength,intcols,robj#,rcon#,match#,refact,nvl(enabled,0),
rowid,cols,nvl(defer,0),mtime,nvl(spare1,0)
from
cdef$ where obj#=:1
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 8 0.00 0.00 0 12 0 7
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 10 0.00 0.00 0 12 0 7
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: CHOOSE
Parsing user id: SYS (recursive depth: 2)
Rows Row Source Operation
------- ---------------------------------------------------
7 TABLE ACCESS CLUSTER CDEF$ (cr=12 pr=0 pw=0 time=21 us)
1 INDEX UNIQUE SCAN I_COBJ# (cr=2 pr=0 pw=0 time=10 us)(object id 30)
********************************************************************************
select intcol#,nvl(pos#,0),col#,nvl(spare1,0)
from
ccol$ where con#=:1
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 7 0.00 0.00 0 0 0 0
Fetch 14 0.00 0.00 0 35 0 7
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 22 0.00 0.00 0 35 0 7
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: CHOOSE
Parsing user id: SYS (recursive depth: 2)
Rows Row Source Operation
------- ---------------------------------------------------
1 TABLE ACCESS BY INDEX ROWID CCOL$ (cr=5 pr=0 pw=0 time=65 us)
1 INDEX RANGE SCAN I_CCOL1 (cr=4 pr=0 pw=0 time=73 us)(object id 54)
********************************************************************************
select col#, grantee#, privilege#,max(mod(nvl(option$,0),2))
from
objauth$ where obj#=:1 and col# is not null group by privilege#, col#,
grantee# order by col#, grantee#
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 0.00 0.00 0 2 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 3 0.00 0.00 0 2 0 0
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: CHOOSE
Parsing user id: SYS (recursive depth: 2)
Rows Row Source Operation
------- ---------------------------------------------------
0 SORT GROUP BY (cr=2 pr=0 pw=0 time=79 us)
0 TABLE ACCESS BY INDEX ROWID OBJAUTH$ (cr=2 pr=0 pw=0 time=62 us)
0 INDEX RANGE SCAN I_OBJAUTH1 (cr=2 pr=0 pw=0 time=57 us)(object id 103)
********************************************************************************
select grantee#,privilege#,nvl(col#,0),max(mod(nvl(option$,0),2))
from
objauth$ where obj#=:1 group by grantee#,privilege#,nvl(col#,0) order by
grantee#
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 0.00 0.00 0 2 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 3 0.00 0.00 0 2 0 0
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: CHOOSE
Parsing user id: SYS (recursive depth: 2)
Rows Row Source Operation
------- ---------------------------------------------------
0 SORT GROUP BY (cr=2 pr=0 pw=0 time=32 us)
0 TABLE ACCESS BY INDEX ROWID OBJAUTH$ (cr=2 pr=0 pw=0 time=17 us)
0 INDEX RANGE SCAN I_OBJAUTH1 (cr=2 pr=0 pw=0 time=15 us)(object id 103)
********************************************************************************
MERGE INTO AE_STATE D USING ( SELECT T.PARAM_ID, T.VALUE, R.ID RES_ID FROM (
SELECT DEVICE_ID, PROFILE_ID, PARAM_ID, NUM , MAX(VALUE) VALUE FROM TABLE(
:B1 ) GROUP BY DEVICE_ID, PROFILE_ID, PARAM_ID, NUM ) T INNER JOIN
AE_PROFILE_DETAIL P ON (P.PROFILE_ID = T.PROFILE_ID AND P.PARAM_ID =
T.PARAM_ID) INNER JOIN AE_RESOURCE R ON ( R.DEVICE_ID = T.DEVICE_ID AND
R.RES_NUM = T.NUM AND R.TYPE_ID = P.TYPE_ID AND R.START_DATE <= SYSDATE AND
SYSDATE <= NVL(R.END_DATE, SYSDATE + 1)) WHERE T.PARAM_ID <> :B2 ) S ON
(D.RES_ID = S.RES_ID AND D.PARAM_ID = S.PARAM_ID) WHEN MATCHED THEN UPDATE
SET D.VALUE = S.VALUE , D.DATETIME = CURRENT_TIMESTAMP WHEN NOT MATCHED
THEN INSERT (ID, PARAM_ID, RES_ID, VALUE) VALUES (AE_STATE_SEQ.NEXTVAL,
S.PARAM_ID, S.RES_ID, S.VALUE)
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.01 0.01 1 12 1016 101
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.01 0.01 1 12 1016 101
Misses in library cache during parse: 0
Optimizer mode: ALL_ROWS
Parsing user id: 977 (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
2 MERGE AE_STATE (cr=126 pr=1 pw=0 time=23502 us)
101 VIEW (cr=125 pr=0 pw=0 time=155950 us)
101 SEQUENCE AE_STATE_SEQ (cr=125 pr=0 pw=0 time=155847 us)
101 HASH JOIN OUTER (cr=115 pr=0 pw=0 time=11697 us)
101 VIEW (cr=54 pr=0 pw=0 time=10526 us)
101 HASH JOIN (cr=54 pr=0 pw=0 time=10423 us)
302 MERGE JOIN (cr=54 pr=0 pw=0 time=1015 us)
101 TABLE ACCESS BY INDEX ROWID AE_RESOURCE (cr=47 pr=0 pw=0 time=9332 us)
101 INDEX FULL SCAN AE_RES_DEV_TYPE_FK (cr=45 pr=0 pw=0 time=8618 us)(object id 823581)
302 SORT JOIN (cr=7 pr=0 pw=0 time=244 us)
5 TABLE ACCESS FULL AE_PROFILE_DETAIL (cr=7 pr=0 pw=0 time=34 us)
101 VIEW (cr=0 pr=0 pw=0 time=8735 us)
101 SORT GROUP BY (cr=0 pr=0 pw=0 time=8633 us)
2000 COLLECTION ITERATOR PICKLER FETCH (cr=0 pr=0 pw=0 time=2014 us)
0 TABLE ACCESS FULL AE_STATE (cr=61 pr=0 pw=0 time=729 us)
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
db file sequential read 1 0.00 0.00
********************************************************************************
COMMIT WRITE NOWAIT
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0
посмотрел distinct.
для начала хорошо бы избавиться от динамического сэмплинга по AE_STATE_TMP — он отжирает ресурсы.
проще всего добавить в выборки из этой таблицы хинт
/*+ dynamic_sampling(t 0) */ — вместо t алиас таблицы. возможно, также залочить по ней статистику dbms_stats.lock_table_stats
для начала хорошо бы избавиться от динамического сэмплинга по AE_STATE_TMP — он отжирает ресурсы.
проще всего добавить в выборки из этой таблицы хинт
/*+ dynamic_sampling(t 0) */ — вместо t алиас таблицы. возможно, также залочить по ней статистику dbms_stats.lock_table_stats
+1
по обычным запросам основное время уходит на
INSERT INTO AE_STATE_LOG
могу посоветовать добавить составные индексы по таблицам
AE_PARAMETER
AE_DOMAIN
AE_STATE_POLICY
AE_THRESHOLD
первым полем в индексе также оставить колонку PK, а набор остальных колонок в индексе должен быть таким, чтобы в плане запроса не было обращения к таблице вообще, а все бралось чисто из индекса.
Это может на порядок ускорить выборку.
Или, как вариант, сделать их идексно-организованными.
INSERT INTO AE_STATE_LOG
могу посоветовать добавить составные индексы по таблицам
AE_PARAMETER
AE_DOMAIN
AE_STATE_POLICY
AE_THRESHOLD
первым полем в индексе также оставить колонку PK, а набор остальных колонок в индексе должен быть таким, чтобы в плане запроса не было обращения к таблице вообще, а все бралось чисто из индекса.
Это может на порядок ускорить выборку.
Или, как вариант, сделать их идексно-организованными.
+1
и какой там код ORA-600?
версия БД, opatch lsinventory?
версия БД, opatch lsinventory?
0
Завтра на работе воспроизведу и отпишу
0
java.sql.BatchUpdateException: ORA-00600: код внутр. ошибки, аргументы: [6704], [2], [0], [8902921], [], [], [], []
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 — 64
Воспроизводится устойчиво на test_temporary при установке достаточно большого BULK_SIZE
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 — 64
Воспроизводится устойчиво на test_temporary при установке достаточно большого BULK_SIZE
0
По коду точный баг не смог найти — их там много разных, но не про временные таблицы.
Полагаю, что должен быть пофикшен в 10.2.0.5 или даже в 10.2.0.4.
Вообще, рекомендую 11.2.0.3 + последний PSU. На 10.2.0.3 даже таймзону в БД проблематично правильную сделать… особенно если есть есть официальная поддержка.
Полагаю, что должен быть пофикшен в 10.2.0.5 или даже в 10.2.0.4.
Вообще, рекомендую 11.2.0.3 + последний PSU. На 10.2.0.3 даже таймзону в БД проблематично правильную сделать… особенно если есть есть официальная поддержка.
0
Можно в студию, сам запрос / код на котором выпадает? То что большей частью выпадает на металинке на ORA-600 [6704] — это ошибки при SELECT FOR UPDATE, но это не ваш случай, а также на партиционированые таблицы, что снова таки, в основном — не ваш случай.
0
Падает, когда merge пытается забатчить несколько записей относящихся к одному счетчику:
private final static String MERGE_VAL_SQL =
"merge into ae_state_tmp d " +
"using ( select ? id,? device_id,? profile_id,? param_id,? num,? value " +
" from dual" +
" ) s " +
"on ( d.device_id = s.device_id and d.profile_id = s.profile_id and " +
" d.param_id = s.param_id and d.num = s.num ) " +
"when matched then " +
" update set d.value = s.value " +
"when not matched then " +
" insert (id, device_id, profile_id, param_id, num, value) " +
" values (s.id, s.device_id, s.profile_id, s.param_id, s.num, s.value)";
0
под insert all полагаю, имелся ввиду forall insert/*+append_values */ c коллекцией?
0
Привет. Вот и xtender подключился. В тредах везде те-же лица :)
Нет, это другое. В этом месте я предлагал заменить два
insert into hist_table select temp_table /*… там ещё куча одинаковых join*/;
insert into hist_table select temp_table /*… там ещё куча одинаковых join*/;
Одним
insert all
into hist_table (cols) values (values)
into hist_table (cols) values (some other values)
select * from temp_table /*… там ещё куча одинаковых join*/;
Но temp-table заменить на коллекцию, а также использовать /*+append */ мы тоже обсуждали, просто в других ветках — читай выше.
Нет, это другое. В этом месте я предлагал заменить два
insert into hist_table select temp_table /*… там ещё куча одинаковых join*/;
insert into hist_table select temp_table /*… там ещё куча одинаковых join*/;
Одним
insert all
into hist_table (cols) values (values)
into hist_table (cols) values (some other values)
select * from temp_table /*… там ещё куча одинаковых join*/;
Но temp-table заменить на коллекцию, а также использовать /*+append */ мы тоже обсуждали, просто в других ветках — читай выше.
0
Я серьезно подумаю про коллекцию, возможно обойдется даже без процедурной обработки
0
Честно говоря, редко здесь читаю и такие вопросы лучше переносить на форум, там мне и удобнее и читаю чаще.
0
Форум? Это ты про sql.ru что-ли?
0
Конечно
0
Мне там некомфортно. Все какие-то аггресивные, по сути говорят мало, а хамства и высокомерия — много. Если бы при этом хотя бы подробно говорили что имеют в виду — ок, а так, как только задаёшь сложный вопрос — никого нету. А по простым «чего с глупостями своими вылез»… Так о чём говорить то?
+1
Я оттуда ушел. Возвращаться не собираюсь. С отдельными персоналиями можно и без форума пообщаться
0
Я там читаю и отвечаю на интересные вопросы. Хамство не защищаю, но какая-то польза от него есть — отсеиваются совсем уж глупые вопросы, которые, как правило, уже есть в faq
0
Если бы ещё был механизм который бы там заодно отсеивал совсем уж рьяных хамов… (За что мне и нравится хабр- думаю пояснять не нужно).
0
Однако уровень специалистов там выше
0
Именно по Oracle, да. Здесь охват шире
0
В целом согласен. Наверное за сложным техническим оракл вопросом, на который я не нашёл бы ответа ни в интернете ни среди коллег, я бы пошёл таки на sql.ru… или на otn.oracle.com.
Но, как-то, по большей части вопросы возникают не чисто по oracle (большинство вопросов по оракл что могут возникнуть уже отвечены где-либо, стоит лишь погуглить), а на стыке технологий, создании хорошей архитектуры в целом итд… и вот в этом плане sql.ru уже вопрос… формат не тот. Всё-таки это уже ближе к каким-то статьям-обсуждениям, не находишь?
Но, как-то, по большей части вопросы возникают не чисто по oracle (большинство вопросов по оракл что могут возникнуть уже отвечены где-либо, стоит лишь погуглить), а на стыке технологий, создании хорошей архитектуры в целом итд… и вот в этом плане sql.ru уже вопрос… формат не тот. Всё-таки это уже ближе к каким-то статьям-обсуждениям, не находишь?
0
Кстати, кроме sqlldr можно использовать родные директ инсерты из oci. В целом же я бы просто передавал большими коллекциями для уменьшения sql*net round-trip'ов
0
При bulk операциях полезно увеличить SDU и поменять настройки TCP.
Полезная презентация на тему настройки Net.
Полезная презентация на тему настройки Net.
+3
По просьбе jan2ary, размещаю его комментарий:
Видел вашу статью на хабре, сам только читатель, поэтому нашел контакт «где-нибудь».
Хотел бы добавить пару слов про кеш на сиквенсе.
Отсутствие кеша на сиквенсе чревато даже в не-RAC системе и даже при однопоточном его (сиквенса) использовании. Кешированные значения берутся (логично) из кеша, некешированные — из таблицы seq$, при этом каждый раз эта таблица обновляется (это можно видеть в рекурсивных запросах трассировки 10046). Само по себе это еще не страшно, но вот то, что эта таблица общая для всех сиквенсов, уже может привести к проблемам, например, если есть несколько таких активно используемых сиквенсов, то они все вместе будут таблицу дергать и, скорее всего, конкурировать за один и тот же ее блок.
Поэтому кешировать сиквенс нужно в 95% случаев, и еще 4.95% случаев — просто неправильное использование сиквенса.
0
Ну, в общем-то, с этим всем никто не спорит. Просто в RAC-система это конкурирование видно особо ярко.
А в одноинстасевой системе, причём в примере — вставка в один поток, этот самый датаблок с большой вероятностью оказывается в database buffer cache, потому проблема не столь ярка (что не отменяет описанного обращения в seq$). Подтверждение чего мы и увидели на цифрах
А в одноинстасевой системе, причём в примере — вставка в один поток, этот самый датаблок с большой вероятностью оказывается в database buffer cache, потому проблема не столь ярка (что не отменяет описанного обращения в seq$). Подтверждение чего мы и увидели на цифрах
0
Sign up to leave a comment.
Загружаем данные в Oracle