【问题标题】:Replacement for scalar function by inline function用内联函数替换标量函数
【发布时间】:2023-04-02 11:13:01
【问题描述】:

我有一个当前使用标量函数的 proc,在 select 语句中两次,如下所述。当我们处理数百万条记录时,用内联函数替换它是否更好的性能。如果是这样应该是什么

CREATE FUNCTION getcategory
(
    @shopping_store CHAR(4),
    @cart_type      CHAR(2),
    @category_type  INT,
    @index_cat_type INT
)
RETURNS INT
BEGIN
    IF @shopping_store IN ('1111','1222','3222') AND @cart_type in ('120')
        RETURN -@category_type
    ELSE IF @shopping_store IN ('4333','54322') AND @cart_type IN ('120')
        RETURN @index_cat_type
    ELSE
    BEGIN
        IF @shopping_store IN ('32214','5432','5654')
            RETURN @category_type
        ELSE
            RETURN -@index_cat_type
    END

    RETURN @category_type
END

【问题讨论】:

  • 内联函数很可能更好。你试过什么吗?将其更改为内联函数非常简单
  • 关于性能方面,将其更改为内联函数几乎肯定会有所帮助,但也会改变您调用它的方式。阅读this article 了解更多详情。顺便说一句,您将参数@cart_type 声明为CHAR(2),然后检查@cart_type in ('120'),这将永远为真,因为@cart_type 只有两个字符。我怀疑这不是预期的行为。

标签: sql-server query-optimization user-defined-functions


【解决方案1】:

所有这些 IF ELSE 都可以转换为单个 case 表达式。然后,您可以将此标量函数转换为内联表值函数。当您声明您拥有数百万行时,这样做的性能优势应该是相当可观的。我还冒昧地将@cart_type 更改为 char(4),因为 GarethD 指出它甚至不能包含“120”。当想要一个负数时,我也使用了显式乘法,因为它很容易错过 - 一开始,当你乘以负 1 时非常清楚。

CREATE FUNCTION getcategory
(
    @shopping_store CHAR(4),
    @cart_type      CHAR(4),
    @category_type  INT,
    @index_cat_type INT
)
RETURNS TABLE as RETURN
    select case 
        when @shopping_store IN ('1111','1222','3222') AND @cart_type in ('120') 
            then -1 * @category_type
        when @shopping_store IN ('4333','54322') AND @cart_type IN ('120')
            then @index_cat_type
        when @shopping_store IN ('32214','5432','5654')
            then @category_type
        ELSE
            -1 * @index_cat_type
    END as CategoryType

【讨论】:

    猜你喜欢
    • 2014-07-24
    • 1970-01-01
    • 1970-01-01
    • 2018-12-06
    • 2014-09-11
    • 2012-02-20
    • 1970-01-01
    • 2012-05-13
    • 1970-01-01
    相关资源
    最近更新 更多