A UDF é uma caixa preta para o otimizador de consulta, portanto, é executada para cada linha. Você está fazendo um cursor linha por linha. Para cada linha em um ativo, procure um id três vezes em outra tabela. Isso acontece quando você usa UDFs escalares ou de várias instruções (UDFs em linha são simplesmente macros que se expandem para a consulta externa)
Um dos muitos artigos sobre o problema é "Funções escalares, inlining e desempenho:um título divertido para um post chato".
As subconsultas podem ser otimizadas para correlacionar e evitar as operações linha por linha.
O que você realmente quer é isso:
SELECT
uc.id AS creator,
uu.id AS updater,
uo.id AS owner,
a.[name]
FROM
asset a
JOIN
user uc ON uc.user_pk = a.created_by
JOIN
user uu ON uu.user_pk = a.updated_by
JOIN
user uo ON uo.user_pk = a.owned_by
Atualização de fevereiro de 2019
O SQL Server 2019 começa a corrigir esse problema.