powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Deterministic function и EXISTS
7 сообщений из 7, страница 1 из 1
Deterministic function и EXISTS
    #40006505
Фотография CyberMax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Firebird 3.0.5.33220.
Создаю функцию:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
CREATE OR ALTER FUNCTION COUNTER_GET (
    PARAM INTEGER NOT NULL)
RETURNS INTEGER NOT NULL DETERMINISTIC
AS
DECLARE VARIABLE COUNTER INTEGER;
BEGIN
    COUNTER = COALESCE(CAST(RDB$GET_CONTEXT('USER_TRANSACTION', 'COUNTER') AS INTEGER), 0) + 1;
    RDB$SET_CONTEXT('USER_TRANSACTION', 'COUNTER', :COUNTER);

    RETURN :PARAM;
END



Как видно из кода, она запоминает, сколько раз ее вызывают.

Запускаю запрос:
Код: sql
1.
2.
3.
4.
5.
6.
SELECT
    R.*
FROM
    RDB$RELATIONS R
WHERE
    R.RDB$RELATION_ID = COUNTER_GET(1)


Он возвращает одну запись с RDB$RELATION_ID = 1. Смотрим, сколько раз вызывалась функция:
Код: sql
1.
SELECT RDB$GET_CONTEXT('USER_TRANSACTION', 'COUNTER') FROM RDB$DATABASE


Результат: 3.
В самой таблице RDB$RELATIONS - 1524 строки. Будем считать, что все ОК.

Теперь выполняем вот такой запрос:
Код: sql
1.
2.
3.
4.
5.
6.
SELECT
    RF.*
FROM
    RDB$RELATION_FIELDS RF
WHERE
    EXISTS(SELECT 1 FROM RDB$RELATIONS R WHERE R.RDB$RELATION_ID = COUNTER_GET(1) AND R.RDB$RELATION_NAME = RF.RDB$RELATION_NAME)


Результат счетчика вызовов: 13222. В самой таблице: 13219 строк. То есть откуда-то взялось еще три вызова.

Вопросы:
1. Откуда лишние вызовы функции? В первом случае их 2 (3 - 1), во втором случае - 3 (13222 - 13219).
2. То, что в случае применения функции в подзапросе, несмотря на то, что она с флагом Deterministic, она все равно вызывается при каждой проверке условия - это баг или недокументированная фича?
В LangRef 3.0 (на русском) написано следующее:
Код: plaintext
1.
2.
3.
4.
Указание инструкции DETERMINISTIC на самом деле нечто вроде «обещания», что код
функции будет возвращать одно и то же. В данный момент детерминистическая функция
считается инвариантом и работает по тем же принципам, что и другие инварианты. Т.е.
вычисляется и кэшируется на уровне текущего выполнения данного запроса.
В данном случае условие одного запроса выполняется.
...
Рейтинг: 0 / 0
Deterministic function и EXISTS
    #40006509
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Лишние вызовы - так работает выборка. Сначала вызывается COUNTER_GET(1) для создания индексного ключа, потом идет индексный скан в RDB$RELATIONS, потом предикат R.RDB$RELATION_ID = COUNTER_GET(1) проверяется заново для каждой выбранной записи (ибо индексный скан нечеткий по своей природе и может возвращать false positives).

Про инварианты и оптимизацию - на текущий момент однократно выполняются только функции без параметров. Иначе придется хранить не просто результат функции, а ассоциативный массив параметр-результат. Который не хочется раздувать безгранично и при сильной вариабельности входных параметров какие-то элементы будут из него вытесняться. Так что все может работать то быстро, то медленно - причем непредсказуемо. Поэтому такую оптимизацию засунули в "долгий ящик".
...
Рейтинг: 0 / 0
Deterministic function и EXISTS
    #40006512
Dimbuch®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
CyberMax,

DETERMINISTIC с селектом из таблиц и тд использовать неправильно.
DETERMINISTIC - указание на то, что при подаче одних и тех же параметров результат всегда один и тот же.
С селектом такое не пройдёт.
...
Рейтинг: 0 / 0
Deterministic function и EXISTS
    #40006513
Dimbuch®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Чёт не дочитал до конца.
Удалить ответ не могу )))
Прошу не принимать во внимание
...
Рейтинг: 0 / 0
Deterministic function и EXISTS
    #40006531
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CyberMax,

что же ты первое предложение пропустил

авторНа самом деле в текущей версии Firebird, не существует кэша хранимых функций с маппингом
входных аргументов на выходные значения.
...
Рейтинг: 0 / 0
Deterministic function и EXISTS
    #40006532
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис,

хотя наверное лучше дописать, что DETERMINISTIC вообще игнорируется для функций с входными параметрами
...
Рейтинг: 0 / 0
Deterministic function и EXISTS
    #40006785
Фотография CyberMax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dimitr,

Спасибо за ответ. Я еще думал, что FB делает, если вариантов входных значений очень много - заново функцию перевызывает, что-ли. А тут после тестов оказалось, что всегда вызывает. Жаль, конечно, что наличии параметров DETERMINISTIC не работает. Я уже в куче мест заложился на это. Буду переделывать.

Симонов Денис,

Да, так будет лучше.
...
Рейтинг: 0 / 0
7 сообщений из 7, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Deterministic function и EXISTS
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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