Asegúrese de borrar las cachés de ejecución y datos entre cada ejecución de prueba.
por ejemplo
DBCC FREEPROCCACHE
DBCC DROPCLEANBUFFERS
Si ejecuta UNION ALL primero y luego ejecuta las 2 selecciones por separado después, los datos ya se almacenarán en la memoria caché, lo que mejorará mucho el rendimiento (por lo tanto, dará la falsa impresión de que el enfoque posterior es más rápido cuando puede no serlo).
Si usó UNION, entonces eso puede ser más lento ya que tiene que aplicar DISTINCT, pero UNION ALL no tiene que hacer eso, por lo que no debería ser diferente.
Actualización:
Eche un vistazo a los planes de ejecución y compárelos - vea si hay alguna diferencia. Puede ver el plan de ejecución haciendo clic en el botón "Incluir plan de ejecución real" en SSMS antes de ejecutar la consulta
Actualización 2:
Según los CTE completos dados, creo que buscaría optimizarlos; no creo que UNION ALL sea realmente el problema.
En mi humilde opinión, lo mejor que puede intentar es trabajar con los CTE uno por uno e intentar optimizar cada uno individualmente para que cuando los combine en la consulta principal, funcionen mejor.
p.ej. para tDictionaryStreets, qué tal probar esto:
SELECT DISTINCT
r.KladrItemName AS RegionName,
a.KladrItemName AS AreaName,
c.KladrItemName AS CityName,
sc.KladrItemName AS SubCityName,
s.StreetName
FROM StreetNames s
JOIN tFoundStreets fs ON s.StreetName = fs.KladrItemName
LEFT JOIN tFoundRegions r ON s.RegionName = r.KladrItemName
LEFT JOIN tFoundAreas a ON s.AreaName = a.KladrItemName
LEFT JOIN tFoundCities c ON s.CityName = c.KladrItemName
LEFT JOIN tFoundSubCities sc ON s.SubCityName = scc.KladrItemName
KladrItemName en cada tabla debe tener al menos un índice. Intente reelaborar tDictionarySubCities de la misma manera con uniones también.