使用临时 table 优化递归 UDF

Optimizing a recursive UDF with a temp table

我有以下函数循环遍历树结构以查看是否有任何子注释包含 属性:

CREATE FUNCTION [dbo].[ufn_FamilyHasCar] ( @PersonId Integer ) RETURNS bit
as
BEGIN
    DECLARE @Out bit = 0
    Declare @Count int
    Select @Count = count(*) from car WHERE owner_id = @PersonId and type = 2
    if @Count = 0
        begin 
            declare @tbl_temp table (personId int)
            Declare @Id int
            insert into @tbl_temp(personId) (select id from person where parent_id = @PersonId) 
            While (Select Count(*) From @tbl_temp) > 0
                Begin
                    Select Top 1 @Id = personId From @tbl_temp
                    set @Out = dbo.ufn_FamilyHasCar(@Id)
                    if @Out = 1
                        break
                    Delete from @tbl_temp Where personId = @Id
                End
        end
    else 
    set @Out = 1
RETURN @Out
END
GO

这似乎是我目前实现的瓶颈,所以我想问一下我是否以及如何提高 udf 的性能?

我会用递归 CTE 替换它:

with pp as (
      select p.id
      from person p
      where p.id = @personid
      union all
      select p.id
      from pp join
           person p
           on pp.parentid = p.id
    )
select (case when count(*) > 0 then 1 else 0 end)
from pp join
     car c
     on pp.id = c.owner_id and type = 2;

COUNT(*) 是表达查询的最清晰的方式。但是,如果有很多匹配项(比如说超过几十个),那么聚合的额外开销就太过分了,您可以改用 exists:

with pp as ( . . .)
select (case when exists (select 1 from pp join car cc on pp.id = c.owner_id and type = 2)
             then 1 else 0
        end);