Я выполняю оператор выбора в отчете, который возвращает 30 строк за 30 мс.Когда я добавляю в предложение SELECT поля, основанные на пользовательской функции, для выполнения одного и того же запроса требуется минут .
Пользовательская функция принимает три параметра - все из основного запроса - выполняетзатем его собственный запрос COUNT () возвращает целочисленный результат.Сам запрос в пользовательской функции выполняется за 10 мс, но при запуске из пользовательской функции он занимает 300 мс.
Скомпилируются ли пользовательские функции каждый раз, когда они встречаются в запросе?В чем может быть причина медлительности?Во времена Oracle (15 лет назад) я привык создавать собственные функции, вставлять их в запросы, и они выполняли свои действия.Являются ли пользовательские функции MySQL принципиально разными?
Редактировать:
Я только что заметил это: если пользовательская функция принимает параметры, переданные ей из запроса, в котором она используется, то она очень медленная.Если я введу жестко запрограммированные значения параметров, то это будет очень быстро.
Например,
SELECT my_func(foo.col1, foo.col2, foo.col2)
FROM foo;
-- 120 seconds for 30 rows
SELECT my_func(1, 2, 3)
FROM foo;
-- 10 milli seconds for 30 rows
Я могу SELECT my_func(x, y, z)
, где x, y и z - любая комбинация значений, которыебудет передан ему в первом примере запроса, и база данных почти не мигает.Я действительно ломаю голову над этим.
Причина, по которой мне нужна эта функция, заключается в том, что я могу запустить отчет в SugarCRM.Плагин для написания отчетов (KReports) дает мне доступ к определенным объектам и отношениям в базе данных, но есть ряд подсчетов, к которым отчет не разрешает доступ.Пользовательская функция была создана для того, чтобы возвращать счетчики (десять из них) для каждой строки, которую возвращает основной отчет, что фактически дает пользователю сводную таблицу значений 10xN.
В отчете каждый раз возвращается только несколько строк.это возвращается, и это то, что дурачило меня.Эти результаты сгруппированы из базовых данных, которые намного больше.Пользовательская функция выполняется (я предполагаю) на основном наборе данных до применения GROUP BY, и поэтому вызывается на порядок больше раз, чем я думал.
Если бы у меня был полный контроль над генерацией SQL в этом отчете, я бы выбрал 30 (групп) строк во внутреннем запросе, а затем обернул его во внешний запрос, чтобы вызвать пользовательскую функцию для этого меньшего набора данных.Похоже, мне придется использовать другой инструмент отчетности, чтобы это исправить.