Пользовательские функции MySQL в предложении SELECT чрезвычайно медленные - PullRequest
1 голос
/ 13 декабря 2011

Я выполняю оператор выбора в отчете, который возвращает 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 (групп) строк во внутреннем запросе, а затем обернул его во внешний запрос, чтобы вызвать пользовательскую функцию для этого меньшего набора данных.Похоже, мне придется использовать другой инструмент отчетности, чтобы это исправить.

1 Ответ

1 голос
/ 13 декабря 2011

В общем, я отвечаю, что пользовательская функция вызывается 7000 раз в запросе, а не 300 раз, как я изначально думал.300 раз будет хорошо для этого отчета, занимающего около 10 секунд.7000 раз занимает более 3 минут и не годится.

Причина в том, что пользовательская функция в предложении SELECT применяется ко всем строкам, полученным в запросе до применения предложения GROUP BY.,GROUP BY уменьшает 700 извлеченных строк до 30 уникальных строк.

Я не могу изменить способ работы запроса в используемом мной инструменте отчетности, поэтому перейду к новому инструменту отчетности, который обеспечивает большую гибкость ибольше контроля над тем, как строится SQL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...