Чтобы узнать наверняка о производительности, вам нужно протестировать.Я провел некоторое тестирование, используя вашу версию (слегка измененную) и рекурсивные версии CTE, предложенные другими.
Я использовал вашу таблицу примеров с 2048 строками в одной иерархии папок, поэтому при передаче 2048 в качестве параметра функциивыполнено 2048 объединений.
Версия цикла:
create function GetEntireLineage1 (@id int)
returns varchar(max)
as
begin
declare @ret varchar(max)
select @ret = folder_name,
@id = parent_id
from Folder
where id = @id
while @@rowcount > 0
begin
select @ret = @ret + '-' + folder_name,
@id = parent_id
from Folder
where id = @id
end
return @ret
end
Статистика:
SQL Server Execution Times:
CPU time = 125 ms, elapsed time = 122 ms.
Рекурсивная версия CTE:
create function GetEntireLineage2(@id int)
returns varchar(max)
begin
declare @ret varchar(max);
with cte(id, name) as
(
select f.parent_id,
cast(f.folder_name as varchar(max))
from Folder as f
where f.id = @id
union all
select f.parent_id,
c.name + '-' + f.folder_name
from Folder as f
inner join cte as c
on f.id = c.id
)
select @ret = name
from cte
where id is null
option (maxrecursion 0)
return @ret
end
Статистика:
SQL Server Execution Times:
CPU time = 187 ms, elapsed time = 183 ms.
Таким образом, между этими двумя версиями циклов более эффективна, по крайней мере, по моим тестовым данным.Вам необходимо проверить свои фактические данные, чтобы убедиться.
Редактировать
Рекурсивный CTE с трюком for xml path('')
.
create function [dbo].[GetEntireLineage4](@id int)
returns varchar(max)
begin
declare @ret varchar(max) = '';
with cte(id, lvl, name) as
(
select f.parent_id,
1,
f.folder_name
from Folder as f
where f.id = @id
union all
select f.parent_id,
lvl + 1,
f.folder_name
from Folder as f
inner join cte as c
on f.id = c.id
)
select @ret = (select '-'+name
from cte
order by lvl
for xml path(''), type).value('.', 'varchar(max)')
option (maxrecursion 0)
return stuff(@ret, 1, 1, '')
end
Статистика:
SQL Server Execution Times:
CPU time = 31 ms, elapsed time = 37 ms.