SELECT子句中的MySQL自定义函数极其缓慢

时间:2011-12-12 23:08:33

标签: mysql performance function

我在报告中运行一个select语句,返回30 mS的30行。当我向SELECT子句添加基于自定义函数的字段时,同一查询需要分钟才能运行。

自定义函数接受三个参数 - 全部来自主查询 - 执行自己的COUNT()查询然后返回整数结果。自定义函数中的查询本身运行速度为10毫秒,但从自定义函数中运行时,需要300毫秒。

每次在查询中遇到自定义函数时都会编译它们吗?缓慢的原因是什么?在我的Oracle时代(15年前),我习惯于创建自定义函数,将它们粘贴到查询中,然后他们会压缩他们的操作。 MySQL自定义函数是否根本不同?

编辑:

我刚刚发现了这一点:如果自定义函数从其使用的查询中获取传递给它的参数,那么它非常慢。如果我输入硬编码的参数值,那么它非常快。

e.g。

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 个答案:

答案 0 :(得分:1)

总之,我的回答是,自定义函数在查询中被调用7000次而不是我原先想象的300次。对于这份报告,300次没问题,大约需要10秒钟。 7000次超过3分钟并不好。

原因是SELECT子句中的自定义函数应用于应用GROUP BY子句之前在查询中检索的所有行。 GROUP BY将检索到的700行减少到仅30个唯一行。

我无法在我正在使用的报告工具中更改查询的工作方式,因此将转移到新的报告工具,该工具可提供更多灵活性并可更好地控制SQL的构建方式。