Вызов функции MySQL

Если я вызываю функцию несколько раз, будет ли она выполняться каждый раз или просто выполняться один раз, и значение будет использоваться через несколько раз? Пример:

 select my_function('filed'),my_function('filed')/field2, 
        (my_function('filed')*field1)/field3,
...... from my_table    where group by filed1;

Мой вопрос: my_function('filed') будет выполняться один раз, а затем результат будет использоваться в my_function('filed')/field2 и (my_function('filed')*field1)/field3 или каждый раз, когда my_function('filed') будет вызываться и выполняться на системном уровне?


person Samiul    schedule 16.01.2013    source источник
comment
функция выполняется каждый раз. Кэшируется ли возвращаемое значение или нет, зависит от реализации.   -  person duffymo    schedule 16.01.2013


Ответы (4)


Почему бы не использовать переменную, которая улавливает значение вашей функции. Например:

declare var_function (datatype(size)); // just to declare proper data type for your function

set var_function = my_function('filed');

select var_function, var_function/field2, 
        (var_function*field1)/field3,

....from my_table    where group by filed1;

в этом случае вы будете повторно использовать результат функции, и вам не нужно будет повторять процесс функции.

person wedev27    schedule 13.03.2014

Возможна некоторая оптимизация, если вы объявите свою функцию как DETERMINISTIC . Но это действительно должно быть детерминировано:

Подпрограмма считается «детерминированной», если она всегда дает один и тот же результат для одних и тех же входных параметров, и «недетерминированной» в противном случае. Если в определении подпрограммы не указано ни DETERMINISTIC, ни NOT DETERMINISTIC, по умолчанию используется значение NOT DETERMINISTIC. Чтобы объявить функцию детерминированной, вы должны явно указать DETERMINISTIC.

Оценка характера подпрограммы основана на «честности» ее создателя: MySQL не проверяет, что подпрограмма, объявленная как DETERMINISTIC, свободна от операторов, дающих недетерминированные результаты. Однако неправильное объявление подпрограммы может повлиять на результаты или производительность. Объявление недетерминированной подпрограммы как DETERMINISTIC может привести к неожиданным результатам, заставив оптимизатор сделать неверный выбор плана выполнения. Объявление детерминированной подпрограммы как NONDETERMINISTIC может привести к снижению производительности из-за того, что доступные оптимизации не будут использоваться. До MySQL 5.0.44 характеристика DETERMINISTIC принимается, но не используется оптимизатором.

person triclosan    schedule 16.01.2013
comment
Большое спасибо за вашу ценную информацию. Мне нужно прояснить одну вещь, которая находится в приведенном выше примере, вы увидите, что я использовал предложение group by, и на самом деле я вычисляю 84 поля, используя 12 сохраненных функций, которые воздействуют на 511 строк. В этой ситуации я должен объявить как DETERMINISTIC явно? - person Samiul; 16.01.2013

Насколько я знаю (не mysql pro), он каждый раз вызывает эту функцию. Ваш план expalin должен показать эту проблему.

Если вы всегда вызываете функцию с одним и тем же аргументом, скорее запрашивайте ее один раз для каждой строки с помощью подзапроса.

select funcvalue, funcvalue/field2, (funcvalue*field1)/field3,...... 
from SELECT( my_function('filed') funcvalue, ... your other columns... 
FROM TABLE )
where group by filed1;
person Najzero    schedule 16.01.2013

Запустить функцию MySQL очень просто.

Войдите в командную строку MySQL с помощью команды:

$> mysql -u root -p

Затем используйте базу данных, используя:

mysql> use database_name

Затем запустите функцию MySQL, используя:

mysql> delimiter //

mysql> CREATE PROCEDURE simpleproc (OUT param1 INT)
    -> BEGIN
    ->   SELECT COUNT(*) INTO param1 FROM t;
    -> END//
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;

mysql> CALL simpleproc(@a);
Query OK, 0 rows affected (0.00 sec)

Вместо процедуры мы можем добавить любую многострочную функцию в приведенном выше примере.

person Sumit Munot    schedule 16.05.2015
comment
это на самом деле не отвечает на вопрос. Кроме того, CALL предназначен только для процедур, а не для функций. - person Sebastianb; 30.05.2017
comment
@Sebastianb, под приглашением разделителя // мы также можем вызывать функции. использование CALL является просто примером для справки процедур. - person Sumit Munot; 08.06.2017