【问题标题】:UDF Performance in MySQLMySQL 中的 UDF 性能
【发布时间】:2010-11-16 21:03:42
【问题描述】:

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

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

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

任何其他人可以在这个问题上阐明的任何观点都将受到赞赏。

【问题讨论】:

    标签: sql mysql sql-server user-defined-functions


    【解决方案1】:

    UDF 存在已知的限制和问题。请看:Are UDFs Harmful to SQL Server Performance?

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

    【讨论】:

    • 起初我认为这是一个相当笼统的答案......但第二篇链接的文章描述了确切我在这里做错了什么。我不觉得很笨吗。对于 udf 来说,这是多么不幸的阿喀琉斯之踵。太糟糕了,当预编译存储过程时,它们没有被周围的查询解析和优化。似乎违背了 udf 的代码封装可以提供的可维护性优势的目的。无论如何,感谢您的及时和相关反馈。我想我侥幸使用了 SQL Server udf,因为它们没有执行本文所述的逐行操作。
    【解决方案2】:

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

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

    首先,请确保您谈论的是实际的 UDF,这不是存储函数。

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

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

    【讨论】:

      猜你喜欢
      • 2014-12-27
      • 1970-01-01
      • 1970-01-01
      • 2012-01-11
      • 2016-11-12
      • 1970-01-01
      • 1970-01-01
      • 2012-09-09
      相关资源
      最近更新 更多