|
Deterministic function и EXISTS
|
|||
---|---|---|---|
#18+
Firebird 3.0.5.33220. Создаю функцию: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
Как видно из кода, она запоминает, сколько раз ее вызывают. Запускаю запрос: Код: sql 1. 2. 3. 4. 5. 6.
Он возвращает одну запись с RDB$RELATION_ID = 1. Смотрим, сколько раз вызывалась функция: Код: sql 1.
Результат: 3. В самой таблице RDB$RELATIONS - 1524 строки. Будем считать, что все ОК. Теперь выполняем вот такой запрос: Код: sql 1. 2. 3. 4. 5. 6.
Результат счетчика вызовов: 13222. В самой таблице: 13219 строк. То есть откуда-то взялось еще три вызова. Вопросы: 1. Откуда лишние вызовы функции? В первом случае их 2 (3 - 1), во втором случае - 3 (13222 - 13219). 2. То, что в случае применения функции в подзапросе, несмотря на то, что она с флагом Deterministic, она все равно вызывается при каждой проверке условия - это баг или недокументированная фича? В LangRef 3.0 (на русском) написано следующее: Код: plaintext 1. 2. 3. 4.
... |
|||
:
Нравится:
Не нравится:
|
|||
08.10.2020, 11:27 |
|
Deterministic function и EXISTS
|
|||
---|---|---|---|
#18+
Лишние вызовы - так работает выборка. Сначала вызывается COUNTER_GET(1) для создания индексного ключа, потом идет индексный скан в RDB$RELATIONS, потом предикат R.RDB$RELATION_ID = COUNTER_GET(1) проверяется заново для каждой выбранной записи (ибо индексный скан нечеткий по своей природе и может возвращать false positives). Про инварианты и оптимизацию - на текущий момент однократно выполняются только функции без параметров. Иначе придется хранить не просто результат функции, а ассоциативный массив параметр-результат. Который не хочется раздувать безгранично и при сильной вариабельности входных параметров какие-то элементы будут из него вытесняться. Так что все может работать то быстро, то медленно - причем непредсказуемо. Поэтому такую оптимизацию засунули в "долгий ящик". ... |
|||
:
Нравится:
Не нравится:
|
|||
08.10.2020, 11:37 |
|
Deterministic function и EXISTS
|
|||
---|---|---|---|
#18+
CyberMax, DETERMINISTIC с селектом из таблиц и тд использовать неправильно. DETERMINISTIC - указание на то, что при подаче одних и тех же параметров результат всегда один и тот же. С селектом такое не пройдёт. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.10.2020, 11:39 |
|
Deterministic function и EXISTS
|
|||
---|---|---|---|
#18+
Чёт не дочитал до конца. Удалить ответ не могу ))) Прошу не принимать во внимание ... |
|||
:
Нравится:
Не нравится:
|
|||
08.10.2020, 11:41 |
|
Deterministic function и EXISTS
|
|||
---|---|---|---|
#18+
CyberMax, что же ты первое предложение пропустил авторНа самом деле в текущей версии Firebird, не существует кэша хранимых функций с маппингом входных аргументов на выходные значения. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.10.2020, 12:04 |
|
Deterministic function и EXISTS
|
|||
---|---|---|---|
#18+
Симонов Денис, хотя наверное лучше дописать, что DETERMINISTIC вообще игнорируется для функций с входными параметрами ... |
|||
:
Нравится:
Не нравится:
|
|||
08.10.2020, 12:06 |
|
Deterministic function и EXISTS
|
|||
---|---|---|---|
#18+
dimitr, Спасибо за ответ. Я еще думал, что FB делает, если вариантов входных значений очень много - заново функцию перевызывает, что-ли. А тут после тестов оказалось, что всегда вызывает. Жаль, конечно, что наличии параметров DETERMINISTIC не работает. Я уже в куче мест заложился на это. Буду переделывать. Симонов Денис, Да, так будет лучше. ... |
|||
:
Нравится:
Не нравится:
|
|||
09.10.2020, 05:00 |
|
|
start [/forum/topic.php?fid=40&fpage=11&tid=1560232]: |
0ms |
get settings: |
9ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
74ms |
get topic data: |
13ms |
get forum data: |
3ms |
get page messages: |
44ms |
get tp. blocked users: |
1ms |
others: | 15ms |
total: | 180ms |
0 / 0 |