对某些枚举使用函数时 SQL 中的性能问题

问题描述 投票:0回答:1

我有一张包含一些州的表格。有些状态意味着正在进行的状态,因为其他程序员可能会使用查询来获取它们, 例如“所有正在进行的订单”等。

我创建了一个这样的函数,因为也许正在进行的订单状态稍后会发生变化:

CREATE FUNCTION [dbo].[fn_GetStates]()
RETURNS TABLE
AS
RETURN
    SELECT CAST('registered' AS VARCHAR(75)) AS OrderState
    UNION ALL
    SELECT 'OnBoardModify' OrderState
    UNION ALL
    SELECT 'OnCanceling' OrderState
    UNION ALL
    SELECT 'OnSending' OrderState

当我使用此功能时,它比旧查询慢。

旧查询

SELECT *
FROM dbo.Order 
WHERE state IN ('OnBoardModify','registered','OnCanceling')

新查询

SELECT *
FROM dbo.Order_MOT  
WHERE OMSOrderState IN (
    SELECT * FROM [dbo].[fn_GetOpenOrderState]()
)

有什么更好的办法吗?

当我使用表格或函数或...时

计划链接

enter image description here

sql sql-server
1个回答
0
投票

在 SQL 查询中使用函数(标量或表值)会破坏可以使用并行性和索引搜索的数据处理集方法,并且需要对表的每一行 (RBAR) 顺序执行该函数。

自 2017 版以来,对优化器(智能查询处理)的改进,尤其是在 FROID 项目(标量 UDF:内对齐)的框架内的改进,允许尽可能将函数的 SQL 重新合并为集合表达式.

如果您的实例是 2019 年或更高版本,您可以通过将 UDF 重新设计为标量函数、重写查询以使用标量函数并检查您的数据库是否处于 2019 年或 2022 年向后兼容模式(具体取决于您的实例)来受益。

否则,请删除此函数并恢复查询中的原始代码。

CREATE FUNCTION [dbo].[fn_GetStates](@state  VARCHAR(100))
RETURNS BIT
AS
BEGIN
RETURN CASE WHEN @state IN ('registered', 'OnBoardModify', 'OnCanceling', 'OnSending') 
              THEN 1 
            ELSE 0 
       END
END;

SELECT *
FROM   dbo.Order 
WHERE  [dbo].[fn_GetStates](state) = 1;
© www.soinside.com 2019 - 2024. All rights reserved.