загадочный запрос оракула - PullRequest
2 голосов
/ 18 марта 2011

если запрос в oracle занимает первый раз, когда он выполняется 11 минут, а в следующий раз, тот же запрос 25 секунд, с очищенным буфером, какова возможная причина? Может ли быть так, что запрос написан неправильно?

set timing on;
set echo on
set lines 999;

insert into elegrouptmp select idcll,idgrpl,0 from elegroup where idgrpl = 109999990;
insert into SLIMONTMP (idpartes, indi, grecptseqs, devs, idcll, idclrelpayl)
    select rel.idpartes, rel.indi, rel.idgres,rel.iddevs,vpers.idcll,nvl(cdsptc.idcll,vpers.idcll)
from
    relbqe rel,
    elegrouptmp ele,
    vrdlpers vpers
    left join cdsptc cdsptc on
            (cdsptc.idclptcl = vpers.idcll and
             cdsptc.cdptcs      = 'NOS')
where
    rel.idtits = '10BCPGE ' and
    vpers.idbqes = rel.idpartes and
    vpers.cdqltptfc = 'N' and
    vpers.idcll = ele.idelegrpl and
    ele.idgrpl = 109999990;

alter system flush shared_pool;
alter system flush buffer_cache;
alter system flush global context;

select /* original */ mvtcta_part_SLIMONtmp.idpartes,mvtcta_part_SLIMONtmp.indi,mvtcta_part_SLIMONtmp.grecptseqs,mvtcta_part_SLIMONtmp.devs,
mvtcta_part_SLIMONtmp.idcll,mvtcta_part_SLIMONtmp.idclrelpayl,mvtcta_part_vrdlpers1.idcll,mvtcta_part_vrdlpers1.shnas,mvtcta_part_vrdlpers1.cdqltptfc,
mvtcta_part_vrdlpers1.idbqes,mvtcta_part_compte1.idcll,mvtcta_part_compte1.grecpts,mvtcta_part_compte1.seqc,mvtcta_part_compte1.devs,mvtcta_part_compte1.sldminud,
mvtcta.idcll,mvtcta.grecptseqs,mvtcta.devs,mvtcta.termel,mvtcta.dtcptl,mvtcta.nusesi,mvtcta.fiches,mvtcta.indl,mvtcta.nuecrs,mvtcta.dtexel,mvtcta.dtvall,
mvtcta.dtpayl,mvtcta.ioi,mvtcta.mtd,mvtcta.cdlibs,mvtcta.libcps,mvtcta.sldinitd,mvtcta.flagtypei,mvtcta.flagetati,mvtcta.flagwarnl,mvtcta.flagdonei,mvtcta.oriindl,
mvtcta.idportfl,mvtcta.extnuecrs
from SLIMONtmp mvtcta_part_SLIMONtmp
left join vrdlpers mvtcta_part_vrdlpers1 on
(
   mvtcta_part_vrdlpers1.idbqes = mvtcta_part_SLIMONtmp.idpartes
   and mvtcta_part_vrdlpers1.cdqltptfc = 'N'
   and mvtcta_part_vrdlpers1.idcll = mvtcta_part_SLIMONtmp.idcll
)
left join compte mvtcta_part_compte1 on
(
   mvtcta_part_compte1.idcll = mvtcta_part_vrdlpers1.idcll
   and mvtcta_part_compte1.grecpts = substr (mvtcta_part_SLIMONtmp.grecptseqs, 1, 2 )
   and mvtcta_part_compte1.seqc = substr (mvtcta_part_SLIMONtmp.grecptseqs, -1  )
   and mvtcta_part_compte1.devs = mvtcta_part_SLIMONtmp.devs
   and (mvtcta_part_compte1.devs = ' ' or ' ' =  ' ')
   and mvtcta_part_compte1.cdpartc not in ( 'L' , 'R' )
)
left join mvtcta mvtcta on
(
   mvtcta.idcll = mvtcta_part_SLIMONtmp.idclrelpayl
   and mvtcta.devs = mvtcta_part_SLIMONtmp.devs
   and mvtcta.grecptseqs = mvtcta_part_SLIMONtmp.grecptseqs
   and mvtcta.flagdonei <> 0
   and mvtcta.devs = mvtcta_part_compte1.devs
   and mvtcta.dtvall > 20101206
)
where 1=1
order by mvtcta_part_compte1.devs,
mvtcta_part_SLIMONtmp.idpartes,
mvtcta_part_SLIMONtmp.idclrelpayl,
mvtcta_part_SLIMONtmp.grecptseqs,
mvtcta.dtvall;

Ответы [ 6 ]

4 голосов
/ 18 марта 2011

"если запрос в oracle занимает первое время выполнено 11 минут, а в следующий раз, тот же запрос 25 секунд, с буфером покраснела, какова возможная причина? "

Дело в том, что очистка буферов БД, вот так ...

alter system flush shared_pool
/

... стирает хранилище данных Oracle, но есть и другие места, где данные кэшируются. Например, есть вероятность, что ваша ОС кеширует свои файлы.

EXPLAIN PLAN хорош в качестве общего руководства о том, как база данных думает, что выполнит запрос, но это только прогноз. Это может быть выброшено плохой статистикой или окружающими условиями. Не стоит объяснять, почему конкретный экземпляр запроса занял столько же времени, сколько и.

Итак, если вы действительно хотите понять, что происходит, когда база данных выполняет конкретный запрос, вам нужно разобраться с проблемой и научиться использовать интерфейс ожидания. Это очень мощный механизм трассировки, который позволяет нам видеть отдельные события, которые происходят в ходе выполнения одного запроса. Каждая версия Oracle расширяла полезность и богатство интерфейса ожидания, но это было необходимо для правильной настройки начиная с Oracle 9i (если не раньше).

Узнайте больше, прочитав Очень хороший обзор Роджера Шрага .

В вашем случае вы захотите запустить трассировку несколько раз. Чтобы упростить сравнение результатов, вы должны использовать отдельный сеанс для каждого выполнения, каждый раз устанавливая событие 10046.

0 голосов
/ 18 марта 2011

Вот Взятие Тома Кита на очистку буферов Oracle в качестве практики тестирования .Достаточно сказать, что он не фанат.Он одобряет подход к попытке эмулировать вашу производственную нагрузку с вашими тестовыми данными («реальная жизнь») и отбрасывать первый и последний прогоны.Точка @ APC о кешировании ОС - это точка Тома - избавиться от этого (нетривиального!) Эффекта, который вам нужен для отказов сервера, а не только базы данных.

0 голосов
/ 18 марта 2011
could it be that the query is written in a bad way?

«плохо» - довольно эмоциональное выражение, но, в общем, да, если запрос выполняется значительно быстрее во второй раз, это обычно означает, что есть способы оптимизировать запрос.

На самом деле оптимизация запроса - это, как говорит APC, скорее вопрос "в грязи". Очевидным кандидатом в вашем примере может быть подстрока - если таблица огромна, а подстрока пропускает индекс, я думаю, что это займет немного времени, и я предполагаю, что результат всех этих операций подстроки где-то кэшируется. .

0 голосов
/ 18 марта 2011

Может быть второй раз, когда план выполнения известен.Может быть, оптимизатору очень сложно найти план выполнения по какой-то причине.Попробуйте установить

alter session set optimizer_max_permutations=100;

и повторите запрос.Посмотрите, имеет ли это какое-то значение.

0 голосов
/ 18 марта 2011

Иногда блок записывается в файловую систему до его фиксации (грязный блок). Когда этот блок читается позже, Oracle видит, что он был незафиксирован. Он проверяет открытую транзакцию и, если транзакция еще не существует, он знает, что изменение было зафиксировано. Поэтому он записывает блок обратно как чистый блок. Это называется отложенной очисткой блока.

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

0 голосов
/ 18 марта 2011

Что еще происходит на коробке, когда вы запускаете эти? Вы можете получить разные тайминги, основанные на других процессах жевания ресурсов. Кроме того, при большом количестве объединений производительность будет зависеть от использования памяти (hash_area_size, sort_area_size и т. Д.) И доступности, поэтому, возможно, вы выполняете разбиение на страницы (проверьте также размер / использование временного пространства). Короче, попробуйте sql_trace и tkprof для более глубокого анализа

...