powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / deterministic stored function: не помнит своих результатов при повторном вызове/упоминании
21 сообщений из 21, страница 1 из 1
deterministic stored function: не помнит своих результатов при повторном вызове/упоминании
    #38581943
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hi all

вот тут dimitr привел пример цикла в 1 млн итераций с бенчмарком произв-сти rdb$get_context -vs- stored_func - vs- stored_func_deterministic.
Вариант deterministic-функции рвёт всех как тузик грелку.

Но там приведет вариант возврата из неё константы, а мну надо возвращать (сингулярный) результат запроса из базы.
Решил сбацать вот такую детерм. функцию:
Код: plaintext
1.
2.
3.
4.
5.
6.
set term ^;
recreate function fz() returns int  deterministic  as
begin
  return (select count(*) from rdb$types, rdb$types);
end
^set term ;^
commit;
- и проверить трейсом статистику её выполнения.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
set term ^;
execute block as
  declare i int = 1000000;
begin
  while (i > 0) do begin
    i = i - 1 - 0*fz();
  end
  suspend;
end^
set term ;^

Trace : всё супер, соединение rdb$types cross join rdb$types было выполнено только 1 раз:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
2014-03-08T23:47:55.6610 (18984:0x7f18bab2ebd8) EXECUTE_STATEMENT_FINISH
        sqlex30 (ATT_253, SYSDBA:NONE, NONE, TCPv4:127.0.0.1)
        /opt/fb30trnk/bin/isql:23673
                (TRA_11601, CONCURRENCY | WAIT | READ_WRITE)

Statement 885:
--------------------------------------------------------------------------
execute block as
  declare i int = 1000000;
begin
  while (i > 0) do begin
    i = i - 1 - 0*fz();
  end
  suspend;
end
0 records fetched
     479 ms, 130032 fetch(es) 

Table                             Natural     Index    Update    Insert   
**************************************************************************
RDB$TYPES                            63252 
Однако,
1) повторный запуск этого же скрипта показал, что к rdb$types опять была ходьба, те же 130032 фетча.
2) если в запросе упомянуть функцию три раза (например), то ФБ выполнит её также три раза так, как будто бы она еще не выполнялась:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
select fz() f1, fz() f2, fz() f3 from rdb$database
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PLAN (RDB$DATABASE NATURAL)
1 records fetched
     100 ms, 390102 fetch(es) 

Table                             Natural     Index
***************************************************
RDB$DATABASE                            1
RDB$TYPES                           189756 
-- такой же результат для derived-варианта:
-- select f1, f2, fz() f3 from (select f1, fz() f2 from (select fz() f1 from rdb$database));
-- и аналогичный результат для:
-- select fz() f1, fz() f2 from rdb$database 
-- where exists(select * from rdb$database 
-- where not exists(select * from rdb$database where fz()=0))
То есть, детерминистик-функция явно умеет НЕ делать работу во время выполнения стейтмента ("пока бегут строки"), но как-то "слабовата на память" при повторном упоминании её же самой внутри выражения этого стейтмента.
И уж тем более ничего не помнит про свои результаты при НОВОМ стейтменте.

Это так и было задумано ?
...
Рейтинг: 0 / 0
deterministic stored function: не помнит своих результатов при повторном вызове/упоминании
    #38581949
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТаблоидИ уж тем более ничего не помнит про свои результаты при НОВОМ стейтменте.

Ну это-то и ежу понятно: не в мировом же эфире ей хранить значение. Ты попробуй посмотреть
что происходит при повторном вызове препарированного запроса.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
deterministic stored function: не помнит своих результатов при повторном вызове/упоминании
    #38581954
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakovпопробуй посмотреть что происходит при повторном вызове препарированного запроса.Попробовал. Как-то взгрустнулось внезапно...

test:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
set term ^;
execute block as
    declare n int =  3 ;
    declare v int;
    declare s varchar(50);
begin
    s='select fz() from rdb$database';
    while(n>0) do begin
        execute statement(s) into v;
        n=n-1;
    end
end^
set term ;^

trace:
Код: 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.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
Trace session ID 5 started
2014-03-09T00:44:46.9850 (18984:0x7f18bab218e0) TRACE_INIT
        SESSION_5


2014-03-09T00:44:46.9850 (18984:0x7f18bab218e0) DETACH_DATABASE
        /opt/fb30trnk/security3.fdb (ATT_8223, SYSDBA:NONE, NONE, <internal>)

2014-03-09T00:44:46.9850 (18984:0x7f18bab218e0) TRACE_FINI
        SESSION_5


2014-03-09T00:44:56.5590 (18984:0x7f18bab218e0) TRACE_INIT
        SESSION_5


2014-03-09T00:44:56.5590 (18984:0x7f18bab218e0)  PREPARE_STATEMENT 
        sqlex30 (ATT_253, SYSDBA:NONE, NONE, TCPv4:127.0.0.1)
        /opt/fb30trnk/bin/isql:23673
                (TRA_11602, READ_COMMITTED | NO_REC_VERSION | WAIT | READ_WRITE)

Statement 916:
-------------------------------------------------------------------------------
execute block as
    declare n int = 3;
    declare v int;
    declare s varchar(50);
begin
    s='select fz() from rdb$database';
    while(n>0) do begin
        execute statement(s) into v;
        n=n-1;
    end
end
      0 ms

2014-03-09T00:44:56.5930 (18984:0x7f18bab218e0) EXECUTE_STATEMENT_FINISH
        sqlex30 (ATT_253, SYSDBA:NONE, NONE, TCPv4:127.0.0.1)
        /opt/fb30trnk/bin/isql:23673
                (TRA_11601, CONCURRENCY | WAIT | READ_WRITE)

Statement 915:
-------------------------------------------------------------------------------
select fz() from rdb$database
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PLAN (RDB$DATABASE NATURAL)
1 records fetched
     33 ms, 130038 fetch(es)

Table                             Natural     Index    Update    Insert    Delete   Backout     Purge   Expunge
***************************************************************************************************************
RDB$DATABASE                            1
RDB$TYPES                           63252  -- раз 

2014-03-09T00:44:56.6270 (18984:0x7f18bab218e0) EXECUTE_STATEMENT_FINISH
        sqlex30 (ATT_253, SYSDBA:NONE, NONE, TCPv4:127.0.0.1)
        /opt/fb30trnk/bin/isql:23673
                (TRA_11601, CONCURRENCY | WAIT | READ_WRITE)

Statement 915:
-------------------------------------------------------------------------------
select fz() from rdb$database
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PLAN (RDB$DATABASE NATURAL)
1 records fetched
     33 ms, 130038 fetch(es)

Table                             Natural     Index    Update    Insert    Delete   Backout     Purge   Expunge
***************************************************************************************************************
RDB$DATABASE                            1
RDB$TYPES                           63252  -- два! 

2014-03-09T00:44:56.6600 (18984:0x7f18bab218e0) EXECUTE_STATEMENT_FINISH
        sqlex30 (ATT_253, SYSDBA:NONE, NONE, TCPv4:127.0.0.1)
        /opt/fb30trnk/bin/isql:23673
                (TRA_11601, CONCURRENCY | WAIT | READ_WRITE)

Statement 915:
-------------------------------------------------------------------------------
select fz() from rdb$database
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PLAN (RDB$DATABASE NATURAL)
1 records fetched
     33 ms, 130038 fetch(es)

Table                             Natural     Index    Update    Insert    Delete   Backout     Purge   Expunge
***************************************************************************************************************
RDB$DATABASE                            1
RDB$TYPES                           63252  -- три! 

2014-03-09T00:44:56.6600 (18984:0x7f18bab218e0) EXECUTE_STATEMENT_FINISH
        sqlex30 (ATT_253, SYSDBA:NONE, NONE, TCPv4:127.0.0.1)
        /opt/fb30trnk/bin/isql:23673
                (TRA_11601, CONCURRENCY | WAIT | READ_WRITE)

Statement 916:
-------------------------------------------------------------------------------
execute block as
    declare n int = 3;
    declare v int;
    declare s varchar(50);
begin
    s='select fz() from rdb$database';
    while(n>0) do begin
        execute statement(s) into v;
        n=n-1;
    end
end
0 records fetched
    101 ms
...
Рейтинг: 0 / 0
deterministic stored function: не помнит своих результатов при повторном вызове/упоминании
    #38581958
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
То, что детерминированность не работает при трёхкратном вызове в одном запросе - понятно,
так желают только извращенцы, на этот случай забили. С разными запросами тоже понятно:
мирового эфира нет. А вот оправдать препарированный запрос в одной не-рц транзакции я не
могу. Недоработочка, похоже...
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
deterministic stored function: не помнит своих результатов при повторном вызове/упоминании
    #38581960
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovС разными запросами тоже понятно: мирового эфира нет.Мировой зефир есть: rdb$get_context() откуда-то берёт при повторном вызове значение для соотв-щей переменной.
Что мешает сделать такое же поведение для determ-функции ?
...
Рейтинг: 0 / 0
deterministic stored function: не помнит своих результатов при повторном вызове/упоминании
    #38581985
NickDee
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТаблоидЧто мешает сделать такое же поведение для determ-функции ?
Нужно вместо "deterministic" написать "constant" :)
...
Рейтинг: 0 / 0
deterministic stored function: не помнит своих результатов при повторном вызове/упоминании
    #38582005
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovА вот оправдать препарированный запрос в одной не-рц транзакции я не могу. Недоработочка, похоже...
препарированный запрос может выполняться в транзакциях с любым уровнем изоляции, поэтому инварианты приходится сбрасывать перед очередным выполнением запроса. Теоретически, можно было бы как-то идентифицировать инварианты всех запросов транзакции в ее рамках и кешировать их значения в ее пуле. Но такого у нас пока нет.
...
Рейтинг: 0 / 0
deterministic stored function: не помнит своих результатов при повторном вызове/упоминании
    #38582008
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТаблоидЭто так и было задумано ?
в текущем коде - да, так. Ничего специально для детерминированных функций без параметров не выдумывалось, она просто считается инвариантом и работает по тем же принципам, что и другие инварианты. Т.е. вычисляется и кешируется на уровне текущего выполнения данного запроса. В будущем можно подумать о кеше значений детерминированных функций на уровне коннекта, с маппингом входных значений на выходные без их повторного вычисления. Но это пока не планировалось к реализации.
...
Рейтинг: 0 / 0
deterministic stored function: не помнит своих результатов при повторном вызове/упоминании
    #38582033
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dimitrНичего специально для детерминированных функций без параметров не выдумывалось, она просто считается инвариантом и работает по тем же принципам, что и другие инварианты.ага, вот оно что...
а я сижу и репу чешу, чего это:
Код: plaintext
1.
2.
3.
4.
5.
set term ^;
recreate function fx( a_n int ) returns varchar(31) deterministic as
begin
  return (select rt.rdb$type_name from rdb$types rt order by rt.rdb$type rows (:a_n) to (:a_n));
end
^set term ;^

- перечитывает rdb$types на каждой строке вот этого:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
SQL> select fx(10) from rdb$formats rows 5;

FX
===============================
ACTIVE
ACTIVE
ACTIVE
ACTIVE
ACTIVE
Trace:
2585 fetches, 1255 NR rdb$types
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
Statement 30:
------------------------------------------
select fx(10) from rdb$formats rows 5
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PLAN (RDB$FORMATS NATURAL)
5 records fetched
      1 ms, 2585 fetch(es)

Table                             Natural 
unge
******************************************
****
RDB$FORMATS                             5 

RDB$TYPES                            1255 
А до выхода официозно-финального 3.0 можно добавить маппинг входных аргументов на выходные значения ?
...
Рейтинг: 0 / 0
deterministic stored function: не помнит своих результатов при повторном вызове/упоминании
    #38582038
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таблоид,

ты помечтай пока, а там посмотрим :-)
...
Рейтинг: 0 / 0
deterministic stored function: не помнит своих результатов при повторном вызове/упоминании
    #38582046
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dimitrты помечтай пока, а там посмотрим :-)я всё таки застолбил мечталку, дабы не утонула.
...
Рейтинг: 0 / 0
deterministic stored function: не помнит своих результатов при повторном вызове/упоминании
    #38582050
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dimitrТеоретически, можно было бы как-то идентифицировать инварианты всех запросов
транзакции в ее рамках и кешировать их значения в ее пуле. Но такого у нас пока нет.

По здравому сну я пришёл к выводу, что это не стоит выделки. Предположим, есть функция,
возвращающая число записей в какой-то таблице. Между запросами оно может измениться даже в
пределах одной транзакции с любым уровнем изоляции. Будет нехорошо, если функция вернёт
старое значение.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
deterministic stored function: не помнит своих результатов при повторном вызове/упоминании
    #38582051
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakovесть функция, возвращающая число записей в какой-то таблице. Между запросами оно может измениться даже в пределах одной транзакции с любым уровнем изоляции. Будет нехорошо, если функция вернёт старое значение.ну так и determ.-функцию здесь нефиг применять.
Зато прикинь, какой шоколад будет, когда в determ-функцию передаем аргумент (= мнемоническому имени какой-нибудь константы приложения), а она наверх ИДшник выдаёт.
Для таблиц, которые практически не меняются - самое оно.
...
Рейтинг: 0 / 0
deterministic stored function: не помнит своих результатов при повторном вызове/упоминании
    #38582585
afgm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dimitrТаблоид,

ты помечтай пока, а там посмотрим :-)
Жаль что не в 3.0. А так мечталось, что слово deterministic будет работать именно для параметрических функций.
Хотя надо признать, что PSQL-функции, при замене подзапросов из процедур дали в некоторых случая прирост на порядки(!), а не только синтаксическое удобство вызова.
...
Рейтинг: 0 / 0
deterministic stored function: не помнит своих результатов при повторном вызове/упоминании
    #38582653
Гхостик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ТаблоидЗато прикинь, какой шоколад будет, когда в determ-функцию передаем аргумент (= мнемоническому имени какой-нибудь константы приложения), а она наверх ИДшник выдаёт.Почему ПК не сделать мнемоническим именем? Чтобы функции потом писать?

ТаблоидДля таблиц, которые практически не меняются - самое оно.result_cache в оракле легко забирает кучу памяти и забивает систему блокировками при вытеснении по lru данных из кэша если комбинаций входных параметров у кэширующих функций достаточно много. Еще одни потенциальные грабли.
...
Рейтинг: 0 / 0
deterministic stored function: не помнит своих результатов при повторном вызове/упоминании
    #38582660
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ГхостикТаблоидЗато прикинь, какой шоколад будет, когда в determ-функцию передаем аргумент (= мнемоническому имени какой-нибудь константы приложения), а она наверх ИДшник выдаёт.Почему ПК не сделать мнемоническим именем? Чтобы функции потом писать?int = 4 байта, мнемоники - до 30, наверное. Умножь на число записей, а если поле индексированное, то и про индексы не забудь (я про дочерние таблицы, ссылающиеся своими полями на справочник констант; у нас есть такие).

ГхостикТаблоидДля таблиц, которые практически не меняются - самое оно.result_cache в оракле легко забирает кучу памяти и забивает систему блокировками при вытеснении по lru данных из кэшаНеудивительно, если по дефолту выделять на него (result_cache) только 1% от шаред-пула.
...
Рейтинг: 0 / 0
deterministic stored function: не помнит своих результатов при повторном вызове/упоминании
    #38582667
Гхостик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Таблоидint = 4 байта, мнемоники - до 30, наверное. Умножь на число записей, а если поле индексированное, то и про индексы не забудь (я про дочерние таблицы, ссылающиеся своими полями на справочник констант; у нас есть такие).Давно уже производительности поставлен приоритет ниже чем удобству разработки. Ну и вот такой объем данных ухудшает производительность линейно, с этим бороться проще (добавлением железа) чем с комбинаторным взрывом или кривыми руками.
...
Рейтинг: 0 / 0
deterministic stored function: не помнит своих результатов при повторном вызове/упоминании
    #38582674
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ГхостикТаблоидint = 4 байта, мнемоники - до 30, наверное. Умножь на число записей, а если поле индексированное, то и про индексы не забудь (я про дочерние таблицы, ссылающиеся своими полями на справочник констант; у нас есть такие).Давно уже производительности поставлен приоритет ниже чем удобству разработки.Тут золотую середину надо искать. Какой толк в удобстве разработки, если в итоге будет тормоз-прога ? Побьют ведь... :-)
И скажи честно: у тебя не было разве случаев поиска+замены по всему приложению какого-то "красивого", но неэффективного, куска кода на некий "некрасивый", но зато быстрый ? Не на этапе разработки, ес-сно, а когда уже эксплуатация пошла.
ГхостикНу и вот такой объем данных ухудшает производительность линейно, с этим бороться проще (добавлением железа) чем с комбинаторным взрывом или кривыми руками.Попробуй замерить DML на таблице с индексами, глубина которых <=3, а затем то же самое, но на индексах с глубиной >=5 (просто страницу базы сделай сначала 16К, а затем 4К, и натолкай в таблицу 100-150 млн строк). Разница *не* будет линейной.
Железо поменять - проще всего (если бабло выделят), но ведь это не решение проблемы, а перенос на другой день.
...
Рейтинг: 0 / 0
deterministic stored function: не помнит своих результатов при повторном вызове/упоминании
    #38582677
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ГхостикПочему ПК не сделать мнемоническим именем?Есть и еще один аргумент против этого. Незначительный, но всё же. Имена констант иногда выбираются неудачно, их надо менять. И тогда в случае, когда они сидят в непосредственно в полях таблиц, надо будет гемороиться с этими таблицами: отрубать индексы с триггерами (чтобы не ждать по 5 часов), делать апдейты, врубать индексы обратно.
А если мнемоники заданы только в справочном поле, то достаточно исправить только исходники.
Повторюсь: это редкий случай, но он таки может произойти.
...
Рейтинг: 0 / 0
deterministic stored function: не помнит своих результатов при повторном вызове/упоминании
    #38582686
Гхостик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ТаблоидИ скажи честно: у тебя не было разве случаев поиска+замены по всему приложению какого-то "красивого", но неэффективного, куска кода на некий "некрасивый", но зато быстрый ? Не на этапе разработки, ес-сно, а когда уже эксплуатация пошла.Было, конечно. Но - это один случай из 100. Ради него выбирать неудобный для разработки способ и в остальных 99?

ТаблоидРазница *не* будет линейной.С таблицей > 1e7 записей разговор всегда особый, с ней можно (и нужно) отдельно повозиться. И пойти на отходы от общих принципов в угоду производительности - можно, денормализация из той же оперы. Но не надо с нее начинать и считать правильным выбором изначально.
...
Рейтинг: 0 / 0
deterministic stored function: не помнит своих результатов при повторном вызове/упоминании
    #38582714
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТаблоидПопробуй замерить DML на таблице с индексами, глубина которых <=3, а затем то же самое, но на индексах с глубиной >=5 (просто страницу базы сделай сначала 16К, а затем 4К, и натолкай в таблицу 100-150 млн строк). Разница *не* будет линейной.
Железо поменять - проще всего (если бабло выделят), но ведь это не решение проблемы, а перенос на другой день.

Зачем? По мне так страницу 4K сегодня уже никто не ставит. Тут выбор обычно стоит между страницей 8K и 16K. ИХМО размер страницы по умолчанию при создании БД в трёшке надо изменить на 8K
...
Рейтинг: 0 / 0
21 сообщений из 21, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / deterministic stored function: не помнит своих результатов при повторном вызове/упоминании
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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