2016-10-04 2 views
0

Мне интересно следующее странное поведение.поведение транзакции с подзапросом

Эта функция должна регистрировать выбранные данные в таблицу ps_cs_corr_data_tb (эта таблица пуста):

create or replace function cs_corr_data(i_id in varchar2, 
             i_key1 in varchar2, 
             i_key2 in varchar2, 
             i_key3 in varchar2, 
             i_key4 in varchar2, 
             i_key5 in varchar2) 
    return number as pragma autonomous_transaction; 
begin 

    insert into ps_cs_corr_data_tb 
    (descr, 
    cs_key_id_01, 
    cs_key_id_02, 
    cs_key_id_03, 
    cs_key_id_04, 
    cs_key_id_05) 
    values 
    (i_id, i_key1, i_key2, i_key3, i_key4, i_key5); 
    commit; 
    return 1; /* insert successful */ 
exception 
    when dup_val_on_index then 
    return 0; 
end; 

Испытание а)

Испытание со следующим отборного заявления является успешным (как и ожидалось):

select b.id, b.key1, b.key2, b.key3, b.key4, b.key5 
    from (select a.id, a.key1, a.key2, a.key3, a.key4, a.key5 
      from (-- test data 
       select '1' as id,'1' as key1,' ' as key2,' ' as key3,' ' as key4,' ' as key5 from dual union all 
       select '1' as id,'2' as key1,' ' as key2,' ' as key3,' ' as key4,' ' as key5 from dual union all 
       select '1' as id,'3' as key1,' ' as key2,' ' as key3,' ' as key4,' ' as key5 from dual union all 
       select '1' as id,'4' as key1,' ' as key2,' ' as key3,' ' as key4,' ' as key5 from dual union all 
       select '1' as id,'5' as key1,' ' as key2,' ' as key3,' ' as key4,' ' as key5 from dual 
       ) a 
     -- some conditions   
     where a.id = '1' 
      and a.key1 = '4') b 
-- log the results of selection   
where cs_corr_data(b.id, b.key1, b.key2, b.key3, b.key4, b.key5) = 1; 

результат отбора:

ID KEY1 KEY2 KEY3 KEY4 KEY5 
1 4     

результат в лесозаготовительной таблице:

select * from ps_cs_corr_data_tb d; 

DESCR CS_KEY_ID_01 CS_KEY_ID_02 CS_KEY_ID_03 CS_KEY_ID_04 CS_KEY_ID_05 
1  4     

До сих пор ожидаемый результат!

Explain Plan:

Plan hash value: 334628103 

------------------------------------------------------------------------- 
| Id | Operation  | Name | Rows | Bytes | Cost (%CPU)| Time  | 
------------------------------------------------------------------------- 
| 0 | SELECT STATEMENT |  |  5 | 90 |  2 (0)| 00:00:01 | 
| 1 | VIEW   |  |  5 | 90 |  2 (0)| 00:00:01 | 
| 2 | UNION-ALL  |  |  |  |   |   | 
|* 3 | FILTER  |  |  |  |   |   | 
| 4 |  FAST DUAL |  |  1 |  |  2 (0)| 00:00:01 | 
|* 5 | FILTER  |  |  |  |   |   | 
| 6 |  FAST DUAL |  |  1 |  |  2 (0)| 00:00:01 | 
|* 7 | FILTER  |  |  |  |   |   | 
| 8 |  FAST DUAL |  |  1 |  |  2 (0)| 00:00:01 | 
|* 9 | FILTER  |  |  |  |   |   | 
| 10 |  FAST DUAL |  |  1 |  |  2 (0)| 00:00:01 | 
|* 11 | FILTER  |  |  |  |   |   | 
| 12 |  FAST DUAL |  |  1 |  |  2 (0)| 00:00:01 | 
------------------------------------------------------------------------- 

Predicate Information (identified by operation id): 
--------------------------------------------------- 

    3 - filter(NULL IS NOT NULL AND "CS_CORR_DATA"('1','1',' ',' ',' ',' 
       ')=1) 
    5 - filter(NULL IS NOT NULL AND "CS_CORR_DATA"('1','2',' ',' ',' ',' 
       ')=1) 
    7 - filter(NULL IS NOT NULL AND "CS_CORR_DATA"('1','3',' ',' ',' ',' 
       ')=1) 
    9 - filter("CS_CORR_DATA"('1','4',' ',' ',' ',' ')=1) 
    11 - filter(NULL IS NOT NULL AND "CS_CORR_DATA"('1','5',' ',' ',' ',' 
       ')=1) 

Test б)

Теперь тот же тест с различной подготовкой тестовых данных (но те же тестовые данные):

select b.id, b.key1, b.key2, b.key3, b.key4, b.key5 
    from (select a.id, a.key1, a.key2, a.key3, a.key4, a.key5 
      from (select '1' as id, 
         to_char(level) as key1, 
         ' ' as key2, 
         ' ' as key3, 
         ' ' as key4, 
         ' ' as key5 
        from dual 
       connect by level <= 5) a 
     where a.id = '1' 
      and a.key1 = '4') b 
where cs_corr_data(b.id, b.key1, b.key2, b.key3, b.key4, b.key5) = 1; 

результата выбора:

ID KEY1 KEY2 KEY3 KEY4 KEY5 
1 4     

результат в лесозаготовительной таблице:

select * from ps_cs_corr_data_tb d; 

DESCR CS_KEY_ID_01 CS_KEY_ID_02 CS_KEY_ID_03 CS_KEY_ID_04 CS_KEY_ID_05 
1  1     
1  2     
1  3     
1  4     
1  5     

Объяснить план:

Plan hash value: 2403765415 

-------------------------------------------------------------------------------------- 
| Id | Operation      | Name | Rows | Bytes | Cost (%CPU)| Time  | 
-------------------------------------------------------------------------------------- 
| 0 | SELECT STATEMENT    |  |  1 | 37 |  2 (0)| 00:00:01 | 
|* 1 | VIEW       |  |  1 | 37 |  2 (0)| 00:00:01 | 
|* 2 | CONNECT BY WITHOUT FILTERING|  |  |  |   |   | 
| 3 | FAST DUAL     |  |  1 |  |  2 (0)| 00:00:01 | 
-------------------------------------------------------------------------------------- 

Predicate Information (identified by operation id): 
--------------------------------------------------- 

    1 - filter("CS_CORR_DATA"("A"."ID","A"."KEY1","A"."KEY2","A"."KEY3","A"."KE 
       Y4","A"."KEY5")=1 AND "A"."ID"='1' AND "A"."KEY1"='4') 
    2 - filter(LEVEL<=5) 

Любые идеи, что здесь происходит?

+0

Кажется, что второй запрос имеет внешний предикат, сдвинутый вниз в подзапрос. Создайте планы выполнения для обоих запросов и обновите свой вопрос, чтобы включить их. – Boneist

+0

@Boneist планы выполнения добавлены. Благодарим за помощь. –

ответ

2

Oracle (наряду с любой реляционной базой данных) может свободно оценивать предикаты в любом порядке, который он ожидает, будет наиболее эффективным. В любом запросе можно сначала оценить предикат функции или сначала оценить предикаты a.id = '1' and a.key1 = '4' или оценить предикат функции между этими двумя предикатами. Похоже, что фактический план, который оптимизатор выбрал во втором случае (по крайней мере, на этот раз), состоял в том, чтобы сначала оценить функцию, когда она решила оценить функцию последней в первом случае. Разумеется, оптимизатор может изменить свой разум завтра в обоих случаях, поэтому вы не должны зависеть от конкретного плана запросов.

+0

Благодарим вас, т. Е. Oracle произвольно меняет условия внутреннего и внешнего операторов выбора (см. Планы выполнения). Я не рассматривал это. –

Смежные вопросы