L'UDF è una casella nera per l'ottimizzatore di query, quindi viene eseguito per ogni riga. Stai eseguendo un cursore riga per riga. Per ogni riga in una risorsa, cerca un ID tre volte in un'altra tabella. Ciò accade quando si utilizzano UDF scalari o con più istruzioni (le UDF in linea sono semplicemente macro che si espandono nella query esterna)
Uno dei tanti articoli sul problema è "Funzioni scalari, inlining e prestazioni:un titolo divertente per un post noioso".
Le sottoquery possono essere ottimizzate per correlare ed evitare le operazioni riga per riga.
Quello che vuoi veramente è questo:
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
Aggiornamento febbraio 2019
SQL Server 2019 inizia a risolvere questo problema.