scalar UDFs performance issue

refer from Inside Miscrsoft SQL Server 2008: T-SQL Programming.

You should be aware that invoking scalar UDFs in queries has a high cost when you provide
the function with attributes from the outer table as inputs. Even when the function only has

a RETURN clause with a scalar expression, it is not considered inline. The overhead of the
function
call per row involves a high cost. You can run a simple performance test to realize
the high cost involved with UDFs compared to inline expressions in a query.
Before you run the performance test, run the code in Listing 2-1 to create an auxiliary table
of numbers called Nums and populate it with 1,000,000 numbers. Note that this book makes
frequent use of this helper table, so you may want to keep it around after creating it.
List ing 2-1 Creating and Populating Auxiliary Table of Numbers

SET NOCOUNT ON;
USE InsideTSQL2008;
IF OBJECT_ID(‘dbo.Nums‘, ‘U‘) IS NOT NULL DROP TABLE dbo.Nums;
CREATE TABLE dbo.Nums(n INT NOT NULL PRIMARY KEY);
DECLARE @max AS INT, @rc AS INT;
SET @max = 1000000;
SET @rc = 1;
INSERT INTO Nums VALUES(1);
WHILE @rc * 2 <= @max
BEGIN
INSERT INTO dbo.Nums SELECT n + @rc FROM dbo.Nums;
SET @rc = @rc * 2;
END
INSERT INTO dbo.Nums
SELECT n + @rc FROM dbo.Nums WHERE n + @rc <= @max;
Turn on the Discard results after execution in SQL Server Management Studio (SSMS), so that
your measurements do not include the time it takes to generate the output.

  

Start by running a query against a million rows from Nums, with an inline expression that
adds 1 to n:

SELECT n, n + 1 AS n_plus_one FROM dbo.Nums WHERE n <= 1000000;

it finished in less than a second. 

Next, create the AddOne scalar UDF:

1 IF OBJECT_ID(‘dbo.AddOne‘, ‘FN‘) IS NOT NULL
2 DROP FUNCTION dbo.AddOne;
3 GO
4 CREATE FUNCTION dbo.AddOne(@i AS INT) RETURNS INT
5 AS
6 BEGIN
7 RETURN @i + 1;
8 END
9 GO

Now run the query using AddOne:

SELECT n, dbo.AddOne(n) AS n_plus_one FROM dbo.Nums WHERE n <= 1000000;

this query ran for five seconds 

Fortunately, there is a solution that allows you

to avoid making such a choice—a solution that allows you to create a UDF without negatively
effecting the performance of the query.
The solution is applicable only when the function is based on a single expression, as opposed
to having a full body with flow. Instead of defining a scalar UDF, define an inline table-valued
UDF that returns a query with no FROM clause, with a single column based on the expression
of interest. I’ll provide more details about inline table-valued UDFs later in the chapter, in
the section “Table-Valued UDFs.” For now, suffice to say that an inline table-valued UDF is
very much like a view that can accept input parameters. Here’s the inline table-valued UDF
version
of AddOne:

IF OBJECT_ID(‘dbo.AddOneInline‘, ‘IF‘) IS NOT NULL
DROP FUNCTION dbo.AddOneInline;
GO
CREATE FUNCTION dbo.AddOneInline(@n AS INT) RETURNS TABLE
AS
RETURN SELECT @n + 1 AS val;
GO

Because this UDF is table-valued, you can’t just call it as part of an expression—you have to

query it. Therefore, to write a scalar expression based on the function call, you have to use a
scalar subquery, like so:

SELECT n, (SELECT val FROM dbo.AddOneInline(n) AS F) AS n_plus_one
FROM dbo.Nums WHERE n <= 1000000;

this query also ran for under a second

The ability to refer to a table UDF within a subquery and pass attributes from the outer
table as input is like an implicit use of the APPLY operator functionality. If you prefer, as an
alternative
you could use the APPLY operator explicitly, like so:

SELECT Nums.n, A.val AS n_plus_one
FROM dbo.Nums
CROSS APPLY dbo.AddOneInline(n) AS A
WHERE n <= 1000000;

this query also ran for under a second

 

时间: 2024-11-06 06:07:35

scalar UDFs performance issue的相关文章

VENUS: The Root Cause of MSMR Performance Issue

(BTW: I use VENUS to mark the report to wish we will run to the goal smoothly.) High-level Description My mentor Heming and I have found that the root cause of MSMR performance issue is: During the process of sending operation from proxy module to co

遇到 Form 性能问题怎么办 performance issue

性能问题是比較复杂的问题. 一般由performance team 负责, 可是常见的情况是, 我们 INV team 定义的 view 不好, 导致查询性能较差. 这个必须由产品组和 performance team 一起来攻克了. 遇到性能问题的话, 几个经常使用的分析方法: 首先要找出性能较差的SQL, 这个要收集SQL trace, 然后转成 tkprof 文件来看. 把SQL 放到 pl/sql developer 里面, 查看运行计划. 非常多时候问题出在没有使用 index, 而是

performance ISSUE

https://blogs.technet.microsoft.com/netmon/2007/01/26/part-2-tcp-performance-expert-and-general-trouble-shooting/

Performance Monitor Usage2:Peformance Counter

Performance Counter 是量化系统状态或活动的一个数值,对于不同的监控目的,需要设置不同的Performance Counter. Performance counters   are measurements of system state or activity. They can be included in the operating system or can be part of individual applications. Windows Performance

Optimizing Item Import Performance in Oracle Product Hub/Inventory

APPLIES TO: Oracle Product Hub - Version 12.1.1 to 12.1.1 [Release 12.1] Oracle Inventory Management - Version 12.1.1 to 12.1.1 [Release 12.1] Oracle Item Master - Version 12.0.6 to 12.0.6 [Release 12] Information in this document applies to any plat

The Accidental DBA:Troubleshooting Performance

最近重新翻看The Accidental DBA,将Troubleshooting Performance部分稍作整理,方便以后查阅.一.Baselines 网友提供的性能基线的含义:每天使用windows性能计数器定时(周期为一个月,具体需要根据自己的需求)收集服务器硬件信息,然后对硬件信息进行分析统计,计算平均值.最大值.最小值,用来与之后每天硬件信息进行比较,从而快速的估算服务器硬件状态. 之前对基线的理解一直停留在使用Perfmon收集几个计数器,然后拿收集到的数值和网上推荐的数值进行对

转贴---Performance Counter(包含最全的Windows计数器解释)

http://support.smartbear.com/viewarticle/55773/ 这个Article中介绍了一个新工具,TestComplete,把其中涉及到性能计数器的部分摘抄出来了.分三部分 1, Windows Performance Counters Describes counters that the test engine retrieves from applications and computers running under a Windows operati

Query runs slow via .NET

Slow in the Application, Fast in SSMS?Understanding Performance Mysteries An SQL text by Erland Sommarskog, SQL Server MVP. Last revision: 2013-08-30.This article is also available in Russian, translated by Dima Piliugin. Introduction When I read var

Yet Another 10 Common Mistakes Java Developers Make When Writing SQL (You Won’t BELIEVE the Last One)--reference

(Sorry for that click-bait heading. Couldn't resist ;-) ) We're on a mission. To teach you SQL. But mostly, we want to teach you how to appreciate SQL. You'll love it! Getting SQL right or wrong shouldn't be about that You're-Doing-It-Wrong? attitude