Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / merge: не совпадают результаты FB и Oracle (again cursor stability ?) / 25 сообщений из 31, страница 1 из 2
15.03.2014, 23:25:00
    #38587327
Таблоид
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
hi all

LI-T3.0.0.30967

DDL:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
create table t(x int, y int);
create table t2(x int, y int);
commit;
insert into t values(5, 1);
insert into t values(4, 2);
insert into t values(3, 3);
insert into t values(2, 4);
insert into t values(1, 5);
commit;
insert into t2 select * from t;
commit;

DML-1 ("просто update"):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
SQL> update t set y=(select count(*) from t where x<>y); select * from t; rollback;

           X            Y
============ ============
           5            4
           4            4
           3            4
           4            4
           1            4
-- OK --

DML-2 (merge, который должен привести вроде бы к тому же самому результату):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
SQL> merge into t using(select x,y from t2) s on t.x=s.y when matched then update set t.y=(select count(*) from t where x<>y); select * from t; rollback;
-- NB: в условии соединения сравнение идёт с полем `y` из таблицы t 2 ; НЕТ поля ` t. y`, которое изменяется
-- (это не допускается в oracle, с которым далее сравниваю; поэтому и была введена таблица `t2`)
           X            Y
============ ============
           5            4
           4            2
           3            4
           4            2
           1            5

Сравниваю с Ora 11.2.g :
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
SH@ORA112G 23:10:40>merge into t using(select x,y from t2) s on (t.x=s.y) when matched then update set t.y=(select count(*) from t where x<>y);

SH@ORA112G 23:10:44>select * from t;

         X          Y
---------- ----------
         5          4
         4          4
         3          4
         2          4
         1          4

Any comments ?
...
Рейтинг: 0 / 0
15.03.2014, 23:38:24
    #38587334
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
ТаблоидAny comments ?
Оракул закэщировал результат подзапроса как инвариант, иначе результат был бы тем же.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
15.03.2014, 23:49:27
    #38587336
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
Таблоид,

я попробовал без таблицы t2

Код: sql
1.
2.
3.
4.
5.
6.
7.
MERGE INTO T
USING RDB$DATABASE
ON 1=1
WHEN MATCHED THEN
    UPDATE SET Y = (SELECT COUNT(*)
                      FROM T
                      WHERE X <> Y);



Код: sql
1.
SELECT * FROM T;



Код: plaintext
1.
2.
3.
4.
5.
X	Y
5	4
4	4
3	3
2	3
1	3

Dimitry Sibiryakov,

инвариант инвариантом, но для запроса

Код: sql
1.
update t set y=(select count(*) from t where x<>y);



даёт результат правильный и не факт что там инвариант был закэширован
...
Рейтинг: 0 / 0
15.03.2014, 23:55:04
    #38587339
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
Симонов Денисне факт что там инвариант был закэширован
План посмотри, там должно быть это видно.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
16.03.2014, 00:04:01
    #38587345
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
Dimitry Sibiryakov,

не там не там не кэшируется

для MERGE

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
Select Expression
    -> Singularity Check
        -> Aggregate
            -> Filter
                -> Table "T2" Full Scan
Select Expression
    ->  Nested Loop Join (inner)
        -> Filter
            -> Table "RDB$DATABASE" Full Scan
        -> Table "T1" Full Scan

для UPDATE

Код: plaintext
1.
2.
3.
4.
5.
6.
Select Expression
    -> Singularity Check
        -> Aggregate
            -> Filter
                -> Table "T" Full Scan
Select Expression
    -> Table "T" Full Scan

стабильность курсора Влад решал не через материализацию, а зачсёт раскрутки undo лога. Ну если это не так путь он меня поправит
...
Рейтинг: 0 / 0
16.03.2014, 00:11:55
    #38587346
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
Dimitry Sibiryakov,

Код: sql
1.
2.
3.
4.
5.
6.
7.
MERGE INTO T T1
USING RDB$DATABASE
ON 1=1
WHEN MATCHED THEN
    UPDATE SET Y = (SELECT COUNT(*)
                      FROM T T2
                      WHERE T2.X <> T2.Y);



я приводил план для вот такого запроса (слегка изменённого).
...
Рейтинг: 0 / 0
16.03.2014, 01:28:05
    #38587359
Таблоид
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
Симонов Денисдля запроса
Код: sql
1.
update t set y=(select count(*) from t where x<>y);

даёт результат правильныйв датском королевстве у "просто" апдейта, кажись, тоже трудности имеются.
Код: sql
1.
update t set y=(select count(*) from t ta join t tb on ta.x<>tb.y);

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
Ora 11.2 & MS SQL 2005:
 X          Y
-- ----------
 5          5
 4          5
 3          5
 2          5
 1          5

FB LI-T3.0.0.30967:

 X            Y
== ============
 5            3
 4            3
 3            3
 4            3
 1            3
Код: sql
1.
update t set y=(select count(*) from t ta join t tb on ta.x<>tb.y);

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
Ora 11.2 & MS SQL 2005:
 X          Y
-- ----------
 5         20
 4         20
 3         20
 2         20
 1         20

FB LI-T3.0.0.30967:

 X            Y
== ============
 5           22
 4           22
 3           22
 4           22
 1           22
...
Рейтинг: 0 / 0
16.03.2014, 01:32:41
    #38587360
Таблоид
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
пардон, первый вариант апдейта такой:
Код: sql
1.
update t set y=(select count(*) from t ta join t tb on ta.x  = tb.y);

(РАВЕНСТВО вместо неравенства).

Занятно, что ФБ 2.5 выполняет его правильно :
Код: plaintext
1.
2.
3.
4.
5.
6.
 X            Y
== ============
 5            5
 4            5
 3            5
 2            5
 1            5
...
Рейтинг: 0 / 0
16.03.2014, 01:50:12
    #38587363
Таблоид
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
Вот попроще пример:

FB:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
SQL> select * from t; -- init data

           X            Y
============ ============
           5            1
           4            2
           3            3
           4            2
           1            5

SQL> update t set y=(select count(*) from t ta where  ta.y=t.x ); select * from t; rollback;

           X            Y
============ ============
           5            1
           4            0
           3            1
           4            0
           1            1

SQL> update t set y=(select count(*) from t ta where  ta.y=t.y ); select * from t; rollback;

           X            Y
============ ============
           5            1
           4            2
           3            1
           4            2
           1            1

Oracle:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
SH@ORA112G 01:39:19>select * from t; -- init data

         X          Y
---------- ----------
         5          1
         4          2
         3          3
         2          4
         1          5
SH@ORA112G 01:39:24>update t set y=(select count(*) from t ta where  ta.y=t.x );
SH@ORA112G 01:39:26>select * from t;

         X          Y
---------- ----------
         5          1
         4          1
         3          1
         2          1
         1          1
SH@ORA112G 01:39:29>rollback;
SH@ORA112G 01:39:59>update t set y=(select count(*) from t ta where  ta.y=t.y );
SH@ORA112G 01:40:15>select * from t;

         X          Y
---------- ----------
         5          1
         4          1
         3          1
         2          1
         1          1
...
Рейтинг: 0 / 0
16.03.2014, 01:59:16
    #38587366
Таблоид
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
"Хьюстон, у нас проблемы".
В следующем DML поле ` y ` меняется на значение скалярного запроса select count(*), в котором это поле ВООБЩЕ НЕ УПОМИНАЕТСЯ.
Ну, и смотрим результат:

FB 3.0:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
SQL> select * from t; -- init data

           X            Y
============ ============
           5            1
           4            2
           3            3
           4            2
           1            5

SQL> update t set  y =(select count(*) from t ta where  ta.x=t.x ); select * from t; rollback;

           X            Y
============ ============
           5            1
           4            2
           3            1
           4            2
           1            1


Oracle 11.2g:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
SH@ORA112G 01:52:12>select * from t; -- init data

         X          Y
---------- ----------
         5          1
         4          2
         3          3
         2          4
         1          5
SH@ORA112G 01:52:15>update t set  y =(select count(*) from t ta where  ta.x=t.x );
SH@ORA112G 01:52:23>select * from t;

         X          Y
---------- ----------
         5          1
         4          1
         3          1
         2          1
         1          1

FB 2.5 выдаёт результат, как Oracle.
Чё-то в трёшке снова поломалось, КМК...
...
Рейтинг: 0 / 0
16.03.2014, 02:30:06
    #38587373
Таблоид
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
И на десерт еще немного.
FB:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
SQL> select * from t;

           X            Y
============ ============
           5            1
           4            2
           3            3
           4            2
           1            5

SQL> insert into t select x,(select max(s) from (select count(x)over(partition by y)s from t)c ) from t; 

           X            Y
============ ============
           5            1
           4            2
           3            3
           4            2
           1            5
           5            2
           4            2
           3            2
           4            2
           1            2

Oracle:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
SH@ORA112G 02:25:55>select * from t;

         X          Y
---------- ----------
         5          1
         4          2
         3          3
         2          4
         1          5
SH@ORA112G 02:25:59>insert into t select x,(select max(s) from (select count(x)over(partition by y)s from t)c ) from t;
SH@ORA112G 02:26:01>select * from t;

         X          Y
---------- ----------
         5          1
         4          2
         3          3
         2          4
         1          5
         5          1
         4          1
         3          1
         2          1
         1          1

Пойду вздремну слегонца. Всем приятных сновидений.

"I'llbe back!" (C) :-)
...
Рейтинг: 0 / 0
16.03.2014, 02:42:39
    #38587375
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
ТаблоидЧё-то в трёшке снова поломалось, КМК...
Это не в трёшке поломалось, а у тебя в столбце Х две четвёрки, так что результат вполне
правильный. Поспать - правильное решение для этой проблемы.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
16.03.2014, 09:25:53
    #38587394
dimitr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
Dimitry SibiryakovПлан посмотри, там должно быть это видно.
не отображается это в плане
...
Рейтинг: 0 / 0
16.03.2014, 10:52:28
    #38587402
Таблоид
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
Dimitry SibiryakovТаблоидЧё-то в трёшке снова поломалось, КМК...
Это не в трёшке поломалось, а у тебя в столбце Х две четвёрки, так что результат вполне
правильный. Поспать - правильное решение для этой проблемы.Да,перегрелся я вчера :(
2 IP / WS : потрите, плз, к ЧМ мои посты, начиная от 15731769 и до этого. Выглядят бестолковым шумом, всё там ОК с апдейтами.
:-[
...
Рейтинг: 0 / 0
16.03.2014, 12:18:59
    #38587429
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
dimitrне отображается это в плане
Мне почему-то показалось, что Денис запускал запрос на Оракуле...
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
16.03.2014, 13:40:16
    #38587474
Таблоид
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
Результат merge как-то связан с физической раскладкой записей
Вот скрипт, который пересоздаёт эти две таблицы с пятью строками, укладывая их каждый раз в random_порядке, и делающий этот самый merge.
"Результат превосходит ожидания": он такой же случайный, как и порядок записей в таблицах t & t2.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
commit;
recreate table t(x int, y int);
recreate table t2(x int, y int);
commit;

insert into t select r1, r2
from (select 6-row_number()over() r1, row_number()over() r2 from rdb$types rows 5)
order by rand();
commit;

--select * from t; 
insert into t2 select * from t order by rand();
commit;
--select * from t2;
merge into t using(select x,y from t2) s on t.x=s.y
when matched
  then update set t.y=(select count(*) from t where x<>y);
 
select * from t; 
rollback;
run
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
SQL> in rand_merge.sql;

           X            Y
============ ============
           1            4
           5            4
           3            4
           2            5
           4            5

SQL> in rand_merge.sql;

           X            Y
============ ============
           2            4
           1            4
           5            4
           3            4
           4            5

SQL> in rand_merge.sql;

           X            Y
============ ============
           5            4
           4            4
           2            3
           3            3
           1            3
...
Рейтинг: 0 / 0
16.03.2014, 14:10:55
    #38587483
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
Блин, оберни уже своё (select count(*) from t where x<>y) в детерминированную функцию...

Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
16.03.2014, 14:28:25
    #38587488
Таблоид
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
и чё, на каждый такой мёрдж свою детерм. ф-цию ваять ? ;-)

Странное дело: если мёрдж реализован как что-то типа этого:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
for 
select s.id, t.f01, t.f02, (select count(*) from source sx join target tx on ...)
from target t
left join source s on t.id = s.id
into s_id, v_f01, v_f01, v_cnt
do begin
  if ( s_id is null ) then
     insert into source (f01, f02, fcnt) values( :v_f01, :v_f02, :v_cnt )
  else
    update source set f01 = :v_f01, f02 = :v_f02, fcnt = :v_cnt where id = s_id;
end

- то каким образом в нём вообще возникает вышепоказанная хрень ?
...
Рейтинг: 0 / 0
16.03.2014, 14:37:10
    #38587496
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
Dimitry Sibiryakov,

тут битва ведь не за результат конкретного запроса, а за правильность выполнения любого запроса как бы он не был записан и что бы там не думал оптимизатор
...
Рейтинг: 0 / 0
16.03.2014, 14:40:11
    #38587500
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
Таблоиди чё, на каждый такой мёрдж свою детерм. ф-цию ваять ? ;-)
Не на каждый. Достаточно на один, чтобы до тебя дошёл смысл первого ответа в этой теме.

Таблоидесли мёрдж реализован как что-то типа этого
С какого перепугу он так должен быть реализован? Он делается так:
Код: sql
1.
2.
3.
4.
for select rdb$db_key from t right join (select x,y from t2) s on t.x=s.y into :k
  if (k is null) // not matching branch
  else // matching branch
   update t set y=(select count(*) from t t3 where t3.x<>t3.y) where rdb$key=:k


Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
16.03.2014, 14:45:17
    #38587504
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
Симонов Денистут битва ведь не за результат конкретного запроса
Угу, тут битва за право мучить хреново спроектированную базу дерьмозапросами и чтобы было
всё так как хочется левой пятке. В морг.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
16.03.2014, 14:49:32
    #38587506
Таблоид
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
Dimitry Sibiryakov битва за право мучить хреново спроектированную базу дерьмозапросами и чтобы было всё так как хочется левой пятке. В морг.Не, погодь! Тут битва за стабильность курсора как бэ... Вековая мечта почти сбылась, осталось поднажать еще чуток...
ЗЫ. И какие бы дерьмозапросы не сыпались в базу, если они синтаксически корректны, то результат их должен быть ПРАВИЛЬНЫМ.
...
Рейтинг: 0 / 0
16.03.2014, 14:59:47
    #38587514
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
ТаблоидНе, погодь! Тут битва за стабильность курсора как бэ...
Стабильность курсора это в пределах одного запроса. На подзапросы она не распространяется
ни в птице, ни в оракуле.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
16.03.2014, 15:06:14
    #38587519
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
Dimitry Sibiryakov,

да ну?
...
Рейтинг: 0 / 0
16.03.2014, 15:19:05
    #38587526
Таблоид
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
Dimitry SibiryakovСтабильность курсора это в пределах одного запроса . На подзапросы она не распространяется ни в птице, ни в оракуле.Может, всё же в пределах одного стейтмента , а не запроса ? http://tracker.firebirdsql.org/browse/CORE-3362
SQL Standard <...> requires that set of records which will be affected by UPDATE\DELETE statements should be evaluated first and real action (UPDATE or DELETE) should use this stable recordset. I.e. action implementation should not affect updating recordset in any way.
PS. В орацле ты не добьёшься случайных результатов вышепоказанного мёрджа, если будешь заталкивать в таблицу строки в random-порядке:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
SH@ORA112G 15:10:54>set feed off
SH@ORA112G 15:11:02>set timing off
SH@ORA112G 15:11:05>create table t(x int, y int);
SH@ORA112G 15:11:16>insert into t select r,6-r from (select level r from dual connect by level<=5)  order by dbms_random.value ;
SH@ORA112G 15:11:35>select * from t;

         X          Y
---------- ----------
         3          3
         2          4
         5          1
         4          2
         1          5
SH@ORA112G 15:11:39>commit;
SH@ORA112G 15:11:45>create table t2(x int, y int);
SH@ORA112G 15:11:55>insert into t2 select * from t;
SH@ORA112G 15:12:02>commit;
SH@ORA112G 15:12:47>merge into t using(select x,y from t2) s on (t.x=s.y) when matched then update set t.y=(select count(*) from t where x<
>y);
SH@ORA112G 15:13:05>select * from t;

         X          Y
---------- ----------
         3          4
         2          4
         5          4
         4          4
         1          4
...
Рейтинг: 0 / 0
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / merge: не совпадают результаты FB и Oracle (again cursor stability ?) / 25 сообщений из 31, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]