SQL Server中的标量,表值和聚合函数之间的区别?

时间:2016-01-12 22:07:31

标签: sql-server function tsql aggregate-functions sqlclr

SQL Server中的标量值,表值和聚合函数有什么区别?从查询中调用它们需要一种不同的方法,还是以相同的方式调用它们?

4 个答案:

答案 0 :(得分:55)

标量函数

标量函数(有时称为用户定义函数/ UDF)返回单个值作为返回值,而不是结果集,并且可以在查询或SET语句中的大多数位置使用,除了FROM子句(可能还有其他地方?)。此外,标量函数可以通过EXEC调用,就像存储过程一样,但是没有多少时间可以使用此功能(有关此功能的更多详细信息,请参阅我对DBA的以下问题的回答。 StackExchange:Why scalar valued functions need execute permission rather than select?)。这些可以在T-SQL和SQLCLR中创建。

  • T-SQL(UDF):

    • 在SQL Server 2019之前:这些标量函数通常是性能问题,因为它们通常针对返回(或扫描)的每一行运行并且始终禁止并行执行计划。
    • 从SQL Server 2019开始:某些T-SQL标量UDF 可以内联,即将其定义直接放入查询中,以便查询不会调用UDF(类似于如何iTVF工作(见下文))。有一些限制可以防止UDF被内联(如果之前不是一个单词,现在就是这样),并且由于几个因素,内联的UDF并不总是内联。可以在数据库,查询和单个UDF级别禁用此功能。有关这个非常酷的新功能的详细信息,请参阅:Scalar UDF Inlining(请务必查看"要求"部分)。
  • SQLCLR(UDF):这些标量函数通常也会按返回或扫描的每一行运行,但与T-SQL UDF相比有两个重要的好处:

    • 从SQL Server 2012开始,如果UDF未执行任何数据访问,并且标记为IsDeterministic = true,则返回值可以常量折叠到执行计划中。在这种情况下,函数不会每行运行。
    • SQLCLR标量函数可以在并行计划()中工作,如果他们不进行任何数据库访问。

表值函数

表值函数(TVF)返回结果集,可用于任何查询的FROM子句,JOINCROSS APPLY / OUTER APPLY,但与简单视图不同,它不能成为任何DML语句的目标(INSERT / UPDATE / DELETE)。这些也可以在T-SQL和SQLCLR中创建。

  • T-SQL MultiStatement(TVF):这些TVF,顾名思义,可以有多个语句,类似于存储过程。它们要返回的结果是否存储在表变量中并在最后返回;意思是,在函数完成处理之前不会返回任何内容。报告给查询优化器(影响执行计划)的估计返回行数取决于SQL Server的版本:

    • 在SQL Server 2014之前:这些总是报告1(是,仅1)行。
    • SQL Server 2014和2016:这些始终报告100行。
    • 从SQL Server 2017开始:默认是报告100行,但在某些情况下,由于新的Interleaved Execution功能,行数将相当准确(基于当前统计信息)。
  • T-SQL内联(iTVF):这些TVF只能是单个语句,而且该语句是完整查询,就像View一样。实际上,Inline TVF本质上是一个View,它接受用于查询的输入参数。它们也不会缓存自己的查询计划,因为它们的定义被放置在使用它们的查询中(与此处描述的其他对象不同),因此它们可以比其他类型的TVF()更好地优化。如果可以在单个查询中处理逻辑,这些TVF表现得非常好并且是首选。

  • SQLCLR(TVF):这些TVF类似于T-SQL MultiStatement TVF,因为它们在内存中构建整个结果集(即使它是交换/页面文件)在最后释放所有这些。报告给查询优化器(影响执行计划)的估计返回行数始终为1000行。鉴于固定行数远非理想,请支持我的请求以允许指定行数:Allow TVFs (T-SQL and SQLCLR) to provide user-defined row estimates to query optimizer

  • SQLCLR Streaming(sTVF):这些TVF允许复杂的C#/ VB.NET代码,就像常规的SQLCLR TVF一样,但它们的特殊之处在于它们将每一行返回到调用查询它们是生成的()。此模型允许调用查询在发送第一个结果后立即开始处理结果,因此查询在查看任何结果之前不需要等待函数的整个过程完成。并且它需要更少的内存,因为结果不会存储在内存中直到进程完成。报告给查询优化器(影响执行计划)的估计返回行数始终为1000行。鉴于固定行数远非理想,请支持我的请求以允许指定行数:Allow TVFs (T-SQL and SQLCLR) to provide user-defined row estimates to query optimizer

聚合函数

用户定义的聚合(UDA)是与SUM()COUNT()MIN()MAX()等类似的聚合,通常需要一个GROUP BY条款。这些只能在SQLCLR中创建,并且该功能是在SQL Server 2005中引入的。此外,从SQL Server 2008开始,UDA已得到增强,允许多个输入参数()。一个特别的缺点是组内没有行排序的知识,因此在SAFE汇编中不可能创建一个运行总计,如果可以保证排序则相对容易。

还请看:

答案 1 :(得分:6)

标量函数返回单个值。它甚至可能与数据库中的表无关。

tabled-valued函数返回符合您选择条件的表中行的指定列。

聚合值函数返回表格行的计算 - 例如求和值。

答案 2 :(得分:0)

标量函数

返回单个值。这就像使用T-SQL语法在其他编程语言中编写函数一样。

表值函数

与上述相比略有不同。返回表值。在此函数的主体内部,您将编写一个将返回确切表的查询。 例如:

CREATE FUNCTION <function name>(parameter datatype)

RETURN table

AS

RETURN

(

-- *write your query here* ---

)

请注意,没有BEGIN&amp;这里有END个陈述。

汇总功能

包含与GROUP子句一起使用的内置函数。例如:SUM()MAX()MIN()AVG()COUNT()是汇总函数。

答案 3 :(得分:0)

Aggregate和Scalar函数都返回单个值,但是Scalar函数基于单个输入 value 参数运行,而Aggregate函数对单个输入 值集 (集合或列名)。标量函数的示例包括字符串函数ISNULL,ISNUMERIC,聚合函数的示例包括AVG,MAX和其他函数,您可以在Microsoft网站的Aggregate Functions部分中找到

表值函数返回表,无论是否存在任何输入参数。可以通过将其用作常规物理表来执行此功能,例如:SELECT * FROM fnGetMulEmployee()

以下链接对于了解两者之间的区别非常有用:https://www.dotnettricks.com/learn/sqlserver/different-types-of-sql-server-functions