5

当查询在 SELECT 或 WHERE 子句中包含对 UDF 的调用时,我注意到 MySQL 查询执行时间呈指数级性能下降。有问题的 UDF 查询本地表以返回标量值 - 因此它们不仅执行算术表达式,而且充当相关子查询。我通过简单地删除 UDF 并使用相关子查询、更复杂的连接等重写来解决了性能问题。

我想如果我只有使用 MySQL 的经验,我会简单地接受这一点,调整我对 UDF 的使用并继续前进。但在使用 MySQL 之前,我在 SQL Server 上工作了 5 年以上。我构建了一个计费系统来处理更大的数据集,并且非常依赖标量和表值用户定义的函数。这些 UDF 还执行查询(即不仅仅是算术运算)。在 SQL Server 上使用用户定义的函数时,我没有遇到这种性能损失。

我想知道的是,这里是否有人足够了解 SQL Server 与 MySQL 的内部结构,可以证实或解释我目前关于 UDF 在两个系统上的性能差异的原因的理论。我的理论是 SQL Server 的优化器评估 UDF 的方式与 MySQL 的不同。也许是因为表引擎在 MySQL 中解耦了?或者,UDF 在 SQL Server 上的使用更为普遍,而 MySQL 引擎的优化器还没有发展到这么远?我在想的是,也许 SQL Server 优化器将包含的 UDF 视为周围查询的一​​部分(如果可能),然后将其与查询的其余部分一起优化?也许我在这里有点离题,但我只是从未见过在 SQL Server 上使用 UDF 会造成这种性能下降。

其他人可以在此问题上发表的任何见解将不胜感激。

4

2 回答 2

2

UDF 有已知的限制和问题。请参阅:UDF 对 SQL Server 性能有害吗?

关于这个主题有很多文章。希望这是非订阅者访问:Beware Row-by-Row Operations in UDF Clothing

于 2009-08-05T02:10:12.717 回答
2

我知道这是一个老问题,但它首先出现在谷歌搜索“MySQL UDF 性能”中并且还没有足够的答案 - 已接受答案中的一个链接已损坏,另一个似乎没有谈论MySQL UDF 的细节。

首先,让我们确保我们谈论的是实际的 MySQL UDF。在 MySQL 中,“存储函数”和 UDF 是有区别的。使用内部存储函数/过程解释器运行存储函数。UDF 是用 C++ 编写的,并被编译成一个共享库,由 MySQL 服务器加载到内存中,当被调用时,它作为机器代码在 CPU 上运行。因此,UDF 性能通常比存储函数好几个数量级。

所以首先,确保你谈论的是实际的 UDF,这不是一个存储函数。

其次,MySQL UDF 的性能取决于它正在执行的算法的性质及其实现的质量。例如,如果您的 UDF 正在测试 1000 字节长的字符串的所有可能的三元组字符,它将检查 10 亿个组合,并且每行大约需要几秒钟。因此,如果删除 UDF 会使您的代码运行得更快,那么下一步就是调试 UDF 本身以确保它以最佳方式编写 - 或者 UDF 试图回答的问题可能无法快速回答。

也就是说,与向其提供数据以进行分析所需的 I/O 相比,回答相对简单问题的编写良好的 UDF 通常快如闪电。

于 2018-06-06T00:23:49.577 回答