function - Смысл флага deterministic

190
15 августа 2018, 22:10

В чём разница между детерменированной и недетерминированной функцией?
Я надеялся, что deterministic заставит СУБД посчитать функцию чистой и закеширует её результат?

The DETERMINISTIC clause for functions is ideal for functions that do not have any non-deterministic components. This means that each time you provide the function with the same parameter values, the result is the same. When you define a function you can simply add the DETERMINISTIC option to the declaration section, making sure that the function (or any functions or procedures it calls) does not depend on the state of session variables or schema objects as the results may vary across invocations. This option instructs the optimizer that it may use a cached result whenever it encounters a previously calculated result.
Source

create function det() returns INTEGER DETERMINISTIC NO SQL return @param;
create function ndet() returns INTEGER NOT DETERMINISTIC NO SQL return @param;
select 
  @param:=5, det() d1, ndet() n1
, @param:=3, det() d2, ndet() n2
, @param:=1, det() d3, ndet() n3
, @param:=7, det() d4, ndet() n4;

Результат:

5, 5, 5, 3, 3, 3, 1, 1, 1, 7, 7, 7

Т.е. я не вижу никакой разницы.

Как понять, в чём разница, и в каких ситуациях она проявляется?

Answer 1

Если вы определяете DETERMINISTIC, это значит, что для одних и тех же параметров функция всегда возвращает одно и то же значение. Соответственно, MySQL по-идее может кешировать значение, чтобы не пересчитывать его для одних и тех же параметров.

Но поддержка DETERMINISTIC в MySQL реализована не полностью, функция будет выполняться всегда.

Пример на MySQL 5.7.22:

create function rr() returns INTEGER DETERMINISTIC return RAND()*1000;
select rr(), rr();
+------+------+
| rr() | rr() |
+------+------+
|  300 |  451 |
+------+------+

Во WHERE выполняется 1 раз:

CREATE FUNCTION r1() returns INTEGER DETERMINISTIC return RAND()*3;
SELECT * FROM (
  SELECT 1 AS ID UNION ALL
  SELECT 2 AS ID UNION ALL
  SELECT 3 AS ID UNION ALL
  SELECT 4 AS ID UNION ALL
  SELECT 5 AS ID
) AS t1
WHERE r1() < ID;

Выведет, например, 1 | 2 | 3, то есть без "выпадов".

Answer 2

По-моему в таком виде обе функции заведомо недетерминированы, т.к. зависят от внешней переменной @param, которая не является параметром функции...

если оформить функцию так:

create function det(param INTEGER) returns INTEGER DETERMINISTIC NO SQL return param;

то ее (по-моему) можно считать детерменированной, т.к. она гарантированно вернет одинаковый результат при вызове с одинаковыми параметрами...

READ ALSO
Как добавить кнопку в инпут? html

Как добавить кнопку в инпут? html

Всем привет, помогите, пожалуйстаКак в HTML добавить <input type="button"> в <input type="text">, чтобы получилось как на фото? Заранее спасибо

180
Css. Высота блока по вертикали!

Css. Высота блока по вертикали!

Есть 3 блока header, content, footer

174
Переключатель в HTML

Переключатель в HTML

Помогите, пожалуйстаКак сделать чтобы при нажатии на кнопку "Для мужчин" поменять изображение, а также в будущем изменять другие элементы?...

159