当一条语句中多次调用同一个UDF时,它会被调用多少次?

2024-03-24

在以下 t-sql 语句中,dbo.FUNC 函数将被调用多少次?

SELECT
    column1,
    column2,
    dbo.FUNC(column3) AS column3
FROM table1
WHERE dbo.FUNC(column3) >= 5
ORDER BY dbo.FUNC(column3) DESC

它会为每行调用多次单独的时间,还是优化器会识别出它在单个语句中被多次使用,并且只调用一次?

我该如何测试这个?我无法插入到函数内部的表中,因此增加计数器将不起作用......


这是无法保证的。

您需要检查执行计划才能找到答案。一些例子。

CREATE FUNCTION dbo.FUNC1(@p1 int)
RETURNS int
AS
BEGIN
    RETURN @p1 + 1
END

GO

CREATE FUNCTION dbo.FUNC2(@p1 int)
RETURNS int
WITH SCHEMABINDING
AS
BEGIN
    RETURN @p1 + 1
END

GO
SELECT 
       OBJECTPROPERTYEX(OBJECT_ID('dbo.FUNC1'), 'IsDeterministic'),
       OBJECTPROPERTYEX(OBJECT_ID('dbo.FUNC2'), 'IsDeterministic') 
GO

FUNC2被建造WITH SCHEMABINDING并被视为确定性的。FUNC1 isn't.

SELECT
    dbo.FUNC1(number) AS FUNC1,
    dbo.FUNC2(number) AS FUNC2
FROM master..spt_values
WHERE dbo.FUNC1(number) >= 5 AND dbo.FUNC2(number) >= 5
ORDER BY dbo.FUNC1(number), dbo.FUNC2(number)

给出计划

  |--Sort(ORDER BY:([Expr1003] ASC, [Expr1004] ASC))
       |--Compute Scalar(DEFINE:([Expr1003]=[test].[dbo].[FUNC1]([master].[dbo].[spt_values].[number])))
            |--Filter(WHERE:([test].[dbo].[FUNC1]([master].[dbo].[spt_values].[number])>=(5) AND [Expr1004]>=(5)))
                 |--Compute Scalar(DEFINE:([Expr1004]=[test].[dbo].[FUNC2]([master].[dbo].[spt_values].[number])))
                      |--Index Scan(OBJECT:([master].[dbo].[spt_values].[ix2_spt_values_nu_nc]))

FUNC1被评估两次(一次在过滤器中,一次在计算标量中,输出用于投影和排序的计算列),FUNC2仅评估一次。

重写为

SELECT
    FUNC1,
    FUNC2
FROM master..spt_values
CROSS APPLY (SELECT dbo.FUNC1(number), dbo.FUNC2(number)) C(FUNC1, FUNC2)
WHERE FUNC1 >= 5 AND FUNC2 >= 5
ORDER BY FUNC1, FUNC2

稍微改变计划,两者都只评估一次

  |--Sort(ORDER BY:([Expr1003] ASC, [Expr1004] ASC))
       |--Filter(WHERE:([Expr1003]>=(5)))
            |--Compute Scalar(DEFINE:([Expr1003]=[test].[dbo].[FUNC1]([master].[dbo].[spt_values].[number])))
                 |--Filter(WHERE:([Expr1004]>=(5)))
                      |--Compute Scalar(DEFINE:([Expr1004]=[test].[dbo].[FUNC2]([master].[dbo].[spt_values].[number])))
                           |--Index Scan(OBJECT:([master].[dbo].[spt_values].[ix2_spt_values_nu_nc]))

现在对查询稍作修改

SELECT
    FUNC1 + 10,
    FUNC2 + 10
FROM master..spt_values
CROSS APPLY (SELECT dbo.FUNC1(number), dbo.FUNC2(number)) C(FUNC1, FUNC2)
WHERE FUNC1 >= 5 AND FUNC2 >= 5
ORDER BY FUNC1, FUNC2

给出与原始结果相反的结果FUNC2被评估两次但是FUNC1只有一次。

  |--Compute Scalar(DEFINE:([Expr1005]=[Expr1003]+(10)))
       |--Sort(ORDER BY:([Expr1003] ASC, [Expr1004] ASC))
            |--Filter(WHERE:([Expr1003]>=(5)))
                 |--Compute Scalar(DEFINE:([Expr1003]=[test].[dbo].[FUNC1]([master].[dbo].[spt_values].[number])))
                      |--Filter(WHERE:([Expr1004]>=(5)))
                           |--Compute Scalar(DEFINE:([Expr1004]=[test].[dbo].[FUNC2]([master].[dbo].[spt_values].[number]), [Expr1006]=[test].[dbo].[FUNC2]([master].[dbo].[spt_values].[number])+(10)))
                                |--Index Scan(OBJECT:([master].[dbo].[spt_values].[ix2_spt_values_nu_nc]))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当一条语句中多次调用同一个UDF时,它会被调用多少次? 的相关文章

  • 从同一个表复制行并更新 ID 列

    我有下表 我已将产品 B 插入其中 它给我的 ID 为 15 然后我有定义表 如下所示 我想选择 ProdID 14 的 ProductDefinition 行并复制相同的行并将其插入到 ProdID 15 中 如下所示 如何使用 SQL
  • 替换 Select 语句中的 NULL 和空字符串

    我有一个专栏可以有NULL或空白区域 即 值 我想用有效值替换这两个值 例如 UNKNOWN 我发现的各种解决方案建议修改表本身内的值 然而 在这种情况下 这不是一个选项 因为数据库用于开发和 或修补得非常差的第三方应用程序 实际上 我认为
  • 从 Perl 脚本 DBI 关闭 MSSQL 服务器

    我正在写一个 perl 脚本 其中我必须关闭我的 mssql 服务器 做一些操作 然后我必须重新启动它 我知道一种方法是使用 netstat 来停止服务 但我不能使用它 所以我尝试安装 DBI 和 DBD ODBC 模块 我可以通过以下代码
  • 将计算列设置为非空时遇到问题

    我在将计算列设置为时遇到问题not null 我想要实现的是C001 C002 等 同时将其设置为not null 我在论坛上读到 这可以通过使用 NULL 值的默认值 0 来实现 E g ISNULL Price Taxes 0 我尝试应
  • 我如何以编程方式从数据库表生成“插入”数据脚本文件?

    有没有一个优雅的基于面向对象的框架 这是我编写的一些代码 用于为数据库中的每个表生成 插入 存储过程 它还处理返回那些具有标识列的表的新 ID 它使用 SQL SMO 其中一些内容与我的项目有些特定 因此如果您有任何疑问 请告诉我 void
  • 修改SQL Server中的默认值

    我正在尝试使用 SQL Server 2008 中的 SQL 语句更改列的默认值 我在很多地方找到了如何在创建表 添加列时设置默认值 但没有找到如何设置它 一旦列已经存在就修改它 这就是我可以用来在添加时设置它的内容 ALTER TABLE
  • #DELETE 在 Access 中查看 SQL Server 表

    今天早上又出现了一个新问题 我的数据库驻留在 SQL Server 上 并使用 Access 作为前端 其中一个已经使用了至少 10 年的数据库今天突然停止工作 我发现这个问题影响了 2 个 可能更多 我没有检查所有 表 当我在访问中打开表
  • SqlCommand返回值参数

    也许查看此代码的其他人能够告诉我为什么 returnID 始终为 0 我正在尝试从插入的记录中检索新的 ID public int AddToInventory int PartID int QtyOnHand int SpokenFor
  • 岛屿和缺口问题

    背景故事 我有一个数据库 其中包含卡车司机的数据点 其中还包含 在卡车上时 驾驶员可以拥有 驾驶员身份 我想做的是按司机 卡车对这些状态进行分组 截至目前 我已尝试使用 LAG LEAD 来提供帮助 这样做的原因是我可以知道驱动程序状态何时
  • 出错时退出并回滚脚本中的所有内容

    我有一个 TSQL 脚本 它可以进行大量数据库结构调整 但在出现故障时让它继续执行并不真正安全 把事情说清楚 使用 MS SQL 2005 它不是一个存储过程 只是一个脚本文件 sql 我所拥有的按以下顺序排列 BEGIN TRANSACT
  • 如何从 SQL Server 的表中获取列名?

    我想查询一个表的所有列的名称 我发现如何做到这一点 Oracle https stackoverflow com q 452464 419956 MySQL https stackoverflow com q 193780 419956 P
  • 如何在sql中查询xml列

    我在 SQL Server 2008 上有一个表 T1 其中包含一个 XML 列 EventXML 我想查询某个节点包含特定值的所有行 更好的是 我想检索不同节点中的值 表T1 T1 EventID int EventTime dateti
  • 为什么 Excel 有时会在工作表名称中添加 $?

    我有时但并非总是发现 Excel 会放置一个 位于工作表名称末尾 但在 Excel 中看不到 只有在尝试使用 C 将其导入 SQL Server 时才可见 我遇到过很多不同的情况 它保留了原始工作表 但也创建了第二个空的 隐藏 工作表 其中
  • 防止从 SSMS 导出的文件中受影响的行条目

    我怎样才能防止这样的条目 123456 rows affected 在文件末尾导出的文本文件中 似乎没有找到选项 谢谢 你可以使用 SET NOCOUNT ON 不设置计数 https learn microsoft com en us s
  • 如何在 SQL 中的时区中使用“America/New_York”

    我有这段代码在 SQL 中运行良好 但是我想使用不同的时区格式 例如 America New York 代替 US Eastern Standard Time SELECT TODATETIMEOFFSET CAST CURRENT TIM
  • 小数除以小数并得到零

    为什么当我这样做时 select CAST 1 AS DECIMAL 38 28 CAST 1625625 AS DECIMAL 38 28 我得到 0 吗 但是当我得到 0 时 select CAST 1 AS DECIMAL 20 10
  • 在调用存储过程 Sql Server 2008 时使用嵌套存储过程结果

    是否可以在另一个存储过程中使用一个存储过程的结果 I e CREATE PROCEDURE dbo Proc1 ID INT mfgID INT DealerID INT AS BEGIN DECLARE Proc1Result UserD
  • SQL查询多行变成单行

    有什么方法可以将通常返回具有相同值的多行的 SQL 查询更改为单行吗 例如 如果我现有的查询返回以下内容 ColA ColB 1 AA 1 BB 1 CC 2 AA 3 AA 我可以将查询更改为仅返回 3 行 并将 1 的第二个和第三个结果
  • T-Sql如何从另一个存储过程中的存储过程返回表

    我想做以下事情 基本上有一个存储过程调用另一个返回表的存储过程 这是怎么做到的 ALTER PROC GETSomeStuff AS BEGIN table exec CB GetLedgerView accountId fromDate
  • SQL 解析键值字符串

    我有一个像这样的逗号分隔字符串 key1 value1 key2 value2 key3 value3 key1 value1 1 key2 value2 1 key3 value3 1 我想将它解析成一个如下所示的表 Key1 Key2

随机推荐

  • 如何强制内联div保持在同一行?

    我正在尝试制作三列布局 我希望左列和右列的宽度仅与其子项内容一样宽 我希望中心柱能够扩大以填充剩余空间 我正在尝试以下操作 概述 下面包含 jsfiddle 链接 colLeft display inline float left colC
  • 在 .NET 异常中保留原始 StackTrace/LineNumbers

    了解之间的区别throw ex and throw 为什么在这个例子中保留了原来的StackTrace static void Main string args try LongFaultyMethod catch System Excep
  • Windows Phone 应用程序缺少 EventToCommand

    我正在使用 MVVM Light 构建 Windows Phone 8 应用程序 到目前为止 一切都很好 但是 当我使用 EventToCommand 时 出现多个错误 一个类似的问题在这里迁移到 SL5 的 v4 时 EventToCom
  • 为什么 C++ 中不允许初始化整型成员变量(不是 const static)?

    当我尝试在类定义中初始化 int 成员变量时 我的 C 编译器会抱怨 它告诉我们 只有静态常量整型数据成员才能在类中初始化 您能否解释一下此限制背后的理由 如果可能的话 举例说明 因为目前的标准是不允许的 根据比亚恩的说法 http www
  • WP7 在地图上拖动图钉

    有谁知道如何在运行 Mango 的 WP7 客户端上的地图上实现可拖动图钉 我有一个图钉绑定到地图上的地理位置 我希望用户能够将其拖动到地图上并记录其新位置 我见过一些资源 但它们用于非 WP7 Bing 地图控制 任何帮助 将不胜感激 T
  • 如何使用 Asset Pipeline 从非标准目录传送字体

    我正在尝试将 Fontawesome 包含在 Rails 4 应用程序中 但资产并未进入资产管道 然而 这些字体并没有在生产中使用 我不明白为什么 文件结构组织 我所有的资产都存储在 assets components因此 Fontawes
  • Node.js 公牛队列中的作业陷入“等待”状态

    我有一堆工作在公牛队列中 其中一个被卡住了 1 个多小时 通常需要大约 2 分钟才能运行 但没有失败 我无法使用我使用的 bull arena UI 将作业从活动状态中删除 因此我删除了 Redis 中活动作业的密钥 这消除了卡住的活动作业
  • php 中的图像验证码

    下面是一个程序的源代码 谁能帮我弄清楚程序的工作原理
  • 在 Android 手机中打开键盘时图像大小调整问题

    感谢您的阅读 我是cordova开发的新手 我正在使用framework7使用cordova开发混合应用程序 我将背景放在登录表单上 但在移动设备中 当打开键盘进行书写时 背景图像会调整大小 我想要修复打开 Android 键盘时未调整大小
  • r-将列表列转换为字符向量,其中列表是字符

    我正在尝试将列表转换为单个字符值 或者基本上从这里开始 test lt data frame a c 1 1 1 2 2 2 b c a b c d e f gt group by a gt summarise b list b to th
  • 在 Elasticsearch 和 Lucene 4.4 中使用 Shingles 和停用词

    在我正在构建的索引中 我有兴趣运行查询 然后 使用方面 返回该查询的带状疱疹 这是我在文本上使用的分析器 settings analysis analyzer shingleAnalyzer tokenizer standard filte
  • 如何检查 AlarmManager 是否已经设置了闹钟?

    当我的应用程序启动时 我希望它检查特定警报 通过 AlarmManager 注册 是否已设置并正在运行 谷歌的结果似乎表明没有办法做到这一点 这仍然正确吗 我需要执行此检查 以便在采取任何操作创建新警报之前向用户提供建议 跟进 ron 发表
  • 如何将数据直接写入显存?

    程序员有什么办法可以直接将数据写入显存吗 我知道操作系统对此非常严格 但是某些类型的应用程序 例如视频播放器或电脑游戏 如何将其数据直接写入视频内存 我知道有很多知名的库 例如 OpenGL 但它们毕竟只是普通的库 它们和我和你写的程序没有
  • 有没有办法在不修改 Yocto 的情况下为机器 ID 创建链接?

    我正在运行使用 Yocto Zeus 3 0 0 构建的 Linux 4 14 149 我正在运行只读文件系统 最近发现一个问题 我的 UID etc machine id 每次启动都会发生变化 这个问题的结果 https superuse
  • wpf应用程序在调试模式下运行,但在没有调试的情况下不会运行

    我的 WPF 应用程序在 VS2015 中以调试模式成功运行 但是 在不调试的情况下启动时 应用程序启动并立即完成 从 Debug Release 文件夹启动 exe 文件时也会发生同样的情况 事件查看器显示以下 Net 运行时错误 应用程
  • 在elasticsearch中存储日期格式

    当我想向 Elasticsearch 添加一个日期时间字符串时 我遇到了一个问题 该文件如下 LastUpdate 2013 07 24 00 00 00 该文档提出了一个错误 即 NumberFormatException For inp
  • WCF服务的启动方法在哪里?

    我需要在第一次调用 wcf 服务之前运行一些方法 我应该将这些方法放在哪里 WCF服务的启动方法在哪里 Obs1 我的 WCF 服务将在 IIS6 上运行 Obs2 我正在使用 net框架4 0 实现此目的的一种方法是自行托管 WCF 服务
  • 如何将 MouseEvents 添加到 AbsolutePanel?

    如何在不创建 Composite widget 的情况下将 MouseEvents 特别是 MouseOutHandlers 添加到 AbsolutePanel 或者这可能吗 据我所知 它涉及添加 DomHandler 和 HandlerR
  • import java.util.*; 和有什么区别并导入java.util.Date; ?

    我只想输出电流 我写了 import java util 一开始 并且 System out println new Date 在主要部分 但我得到的是这样的 Date 124bbbf 当我将导入更改为import java util Da
  • 当一条语句中多次调用同一个UDF时,它会被调用多少次?

    在以下 t sql 语句中 dbo FUNC 函数将被调用多少次 SELECT column1 column2 dbo FUNC column3 AS column3 FROM table1 WHERE dbo FUNC column3 g