Oracle и оценка функции SQLServer в запросах

Да, иначе MD5 был бы бесполезен для таких вещей, как проверка файла. Какую причину вы бы назвали недетерминированным результатом?

5
задан Pablo Santa Cruz 17 June 2009 в 18:13
поделиться

3 ответа

Ответ для Oracle - это зависит. Функция будет вызываться для каждой выбранной строки, ЕСЛИ функция не помечена как «Детерминированная», и в этом случае она будет вызываться только один раз.

CREATE OR REPLACE PACKAGE TestCallCount AS
    FUNCTION StringLen(SrcStr VARCHAR) RETURN INTEGER;
    FUNCTION StringLen2(SrcStr VARCHAR) RETURN INTEGER DETERMINISTIC;
    FUNCTION GetCallCount RETURN INTEGER;
    FUNCTION GetCallCount2 RETURN INTEGER;
END TestCallCount;

CREATE OR REPLACE PACKAGE BODY TestCallCount AS
    TotalFunctionCalls INTEGER := 0;
    TotalFunctionCalls2 INTEGER := 0;

    FUNCTION StringLen(SrcStr VARCHAR) RETURN INTEGER AS
    BEGIN
        TotalFunctionCalls := TotalFunctionCalls + 1;
        RETURN Length(SrcStr);
    END;
    FUNCTION GetCallCount RETURN INTEGER AS
    BEGIN
        RETURN TotalFunctionCalls;
    END;

    FUNCTION StringLen2(SrcStr VARCHAR) RETURN INTEGER DETERMINISTIC AS
    BEGIN
        TotalFunctionCalls2 := TotalFunctionCalls2 + 1;
        RETURN Length(SrcStr);
    END;
    FUNCTION GetCallCount2 RETURN INTEGER AS
    BEGIN
        RETURN TotalFunctionCalls2;
    END;

END TestCallCount;




SELECT a,TestCallCount.StringLen('foo') FROM(
    SELECT 0 as a FROM dual
    UNION
    SELECT 1 as a FROM dual
    UNION
    SELECT 2 as a FROM dual
);

SELECT TestCallCount.GetCallCount() AS TotalFunctionCalls FROM dual;

Вывод:

A                      TESTCALLCOUNT.STRINGLEN('FOO') 
---------------------- ------------------------------ 
0                      3                              
1                      3                              
2                      3                              

3 rows selected


TOTALFUNCTIONCALLS     
---------------------- 
3                      

1 rows selected

Таким образом, функция StringLen () вызывалась три раза в первом случае. Теперь при выполнении с StringLen2 (), которая обозначена как детерминированная:

SELECT a,TestCallCount.StringLen2('foo') from(
    select 0 as a from dual
    union
    select 1 as a from dual
    union
    select 2 as a from dual
);

SELECT TestCallCount.GetCallCount2() AS TotalFunctionCalls FROM dual;

Результаты:

A                      TESTCALLCOUNT.STRINGLEN2('FOO') 
---------------------- ------------------------------- 
0                      3                               
1                      3                               
2                      3                               

3 rows selected

TOTALFUNCTIONCALLS     
---------------------- 
1                      

1 rows selected

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

Для функции, не отмеченной детерминированной, вы можете обойти это, изменив ваш запрос как таковой:

select a, b, c, hashed
  from my_table
cross join (
  select dbms_crypto.hash(utl_raw.cast_to_raw('HELLO'),3) as hashed from dual
);
8
ответ дан 18 December 2019 в 14:50
поделиться

Для SQL-сервера он будет оцениваться для каждой отдельной строки.

Вам будет НАМНОГО лучше, если вы запустите функцию один раз и назначите переменную, а затем используйте переменную. в запросе.

4
ответ дан 18 December 2019 в 14:50
поделиться

короткий ответ .... это зависит.

Если функция обращается к данным, ORACLE не знает, будут ли они одинаковыми для каждой строки, поэтому ему необходимо запросить для каждого. Если, например, ваша функция - это просто средство форматирования, которое всегда возвращает одно и то же значение, вы можете включить кеширование (пометив его как детерминированное), что может позволить вам выполнить вызов функции только один раз.

Что-то, что вы можете захотеть изучить подзапрос ORACLE WITH:

Предложение WITH query_name позволяет присвоить имя блоку подзапроса. Вы затем может ссылаться на блок подзапроса несколько мест в запросе указание имени запроса. Oracle оптимизирует запрос, обрабатывая имя запроса в виде встроенного представления или в качестве временной таблицы

Я взял цитируемый текст из здесь , в котором есть множество примеров.

1
ответ дан 18 December 2019 в 14:50
поделиться
Другие вопросы по тегам:

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