【问题标题】:SQL UDF speed in subquery vs in declare子查询中的 SQL UDF 速度与声明中的速度
【发布时间】:2018-04-09 09:33:16
【问题描述】:
  1. 我创建了一个获取最后一个工作日的 UDF,它在不到 1 秒的时间内运行。
SELECT BlackWidow.dbo.LastBusinessDay('2015-12-31',DEFAULT)
  1. 我还创建了一个返回表的 UDF,它在 1 秒内运行。
SELECT * 
FROM  BlackWidow.dbo.TurnoverTradesMarketCapCountry ('2015-12-31', 50, 20, 50, 100000, 1000000000, 3, 'Brazil')
  1. 当我同时运行两者时,运行时间超过一分钟
SELECT * 
FROM  BlackWidow.dbo.TurnoverTradesMarketCapCountry (BlackWidow.dbo.LastBusinessDay('2015-12-31',DEFAULT), 50, 20, 50, 100000, 1000000000, 3, 'Brazil')
  1. 如果我运行如下代码,只需要 1 秒
DECLARE @date as DATETIME

SET @date=BlackWidow.dbo.LastBusinessDay('2015-12-31',DEFAULT)

SELECT * 
FROM  BlackWidow.dbo.TurnoverTradesMarketCapCountry (@date, 50, 20, 50, 100000, 1000000000, 3, 'Brazil')

任何建议为什么在案例 3 中比在案例 4 中花费更多时间?

【问题讨论】:

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


【解决方案1】:

性能差异最可能的解释是 SQL Server 中的查询优化器无法正确估计第一个查询中的查询成本。优化器不知道函数的返回值是什么,因此它无法在执行前估计查询的适当成本。此限制意味着可能会选择执行极差的查询计划。

优化器评估第二个查询要容易得多,因为一旦分配了@date 变量,查询优化器就能够以更经济的方式计算查询执行成本。

这些操作在功能上是相同的,但在由 SQL Server 执行时它们实际上并不相同。要确认您可以查看估计的查询执行并查看 SQL 优化器的估计成本差异。然后运行查询并查看实际的执行计划。即使在功能上它们完成相同的事情,它们也不会相同。

【讨论】:

  • OP 说性能最好的查询使用 variable - 变量的值不会被嗅探(除非使用 OPTION (RECOMPILE)
猜你喜欢
  • 2011-09-05
  • 1970-01-01
  • 2013-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-11
  • 1970-01-01
  • 2017-12-24
相关资源
最近更新 更多