Почему DBMS_MVIEW.REFRESH имеет неявную фиксацию?

Общее время выполнения против суммы единственного времени выполнения

Care! делительная сумма N округленных времени выполнения является неточным! [1139 ]

Вместо этого мы могли бы разделить общее время выполнения N итерации (на N)

avg_time_alt() { 
    local -i n=$1
    local foo real sys user
    shift
    (($# > 0)) || return;
    { read foo real; read foo user; read foo sys ;} < <(
        { time -p for((;n--;)){ "$@" &>/dev/null ;} ;} 2>&1
    )
    printf "real: %.5f\nuser: %.5f\nsys : %.5f\n" $(
        bc -l <<<"$real/$n;$user/$n;$sys/$n;" )
}

Примечание: Используется bc вместо awk для вычисления среднего. Для этого мы создадим временный файл bc:

printf >/tmp/test-pi.bc "scale=%d;\npi=4*a(1);\nquit\n" 60

Это вычислит с 60 десятичными знаками, а затем спокойно выйдет. (Вы можете адаптировать количество десятичных знаков для вашего хоста.)

Демонстрация:

avg_time_alt 1000 sleep .001
real: 0.00195
user: 0.00008
sys : 0.00016

avg_time_alt 1000 bc -ql /tmp/test-pi.bc
real: 0.00172
user: 0.00120
sys : 0.00058

Где функция codeforester будет anser:

avg_time 1000 sleep .001
real 0.000000
user 0.000000
sys 0.000000

avg_time 1000 bc -ql /tmp/test-pi.bc
real 0.000000
user 0.000000
sys 0.000000

Альтернатива, вдохновленная ответом Чоробы , использующим Linux /proc

Хорошо, вы можете рассмотреть:

avgByProc() { 
    local foo start end n=$1 e=$1 values times
    shift;
    export n;
    { 
        read foo;
        read foo;
        read foo foo start foo
    } < /proc/timer_list;
    mapfile values < <(
        for((;n--;)){ "$@" &>/dev/null;}
        read -a endstat < /proc/self/stat
        {
            read foo
            read foo
            read foo foo end foo
        } 

Это основано на [ 1113]:

man 5 proc | grep [su]time\\\|timer.list | sed  's/^/>   /'
            (14) utime  %lu
            (15) stime  %lu
            (16) cutime  %ld
            (17) cstime  %ld
     /proc/timer_list (since Linux 2.6.21)
blockquote>

Тогда теперь:

avgByProc 1000 sleep .001
real   : 0.00242
utime  : 0.00015
stime  : 0.00021
cutime : 0.00082
cstime : 0.00020

Где utime и stime представляют время пользователя и [ 1130] системное время для самого bash, а cutime и cstime представляют дочернее время пользователя и дочернее системное время , которые являются наиболее интересными .

Примечание: В этом случае (sleep) команда не будет использовать много ресурсов.

avgByProc 1000 bc -ql /tmp/test-pi.bc
real   : 0.00175
utime  : 0.00015
stime  : 0.00025
cutime : 0.00108
cstime : 0.00032

Это становится более понятным ... Конечно, при доступе к timer_list и self/stat последовательно, но не атомарно , различия между real (на основе наносек ) и c?[su]time (основываясь на тиках , т. е. 1/100-й секунде) могут появиться!

6
задан Nick Pierpoint 6 May 2009 в 09:48
поделиться

3 ответа

Depending on your Oracle version and/or the parameters you supply dbms_mview.refresh may be doing a TRUNCATE followed by a direct load. TRUNCATE is a DDL command and as such issues an implicit commit. Direct load does not require a commit.

If you are using a more recent version of Oracle, I think 10.2+, you can set the atomic_refresh parameter to TRUE and it will refresh within a single transaction, using standard DELETE / INSERTs. This method could be quite a bit slower though.

2
ответ дан 16 December 2019 в 21:45
поделиться

По словам Тома Кайта, это потому, что было принято решение во время разработки, чтобы рассмотреть обновление как операцию DDL . Поскольку все операции DDL неявно фиксируются, то же самое происходит и с этой. К сожалению, он не отвечает на возникающий вопрос, почему они решили сделать его DDL.

6
ответ дан 16 December 2019 в 21:45
поделиться

A work arround is to do the call to dbms_mview.refresh in an autonomous transaction (create a PL/SQL procedure with pragma autonomous_transaction).

0
ответ дан 16 December 2019 в 21:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: