Tara Kizer gives a scenario where using sp_executesql can result in lower CPU utilization than EXEC:
For frequently executed queries, “EXEC sp_executesql @sql”is a good choice but at the risk of encountering parameter sniffing issues.
For queries that aren’t executed very often, “EXEC (@sql)” can be used, but you could end up with a bloated plan cache with lots of single-use execution plans.
Let’s compare the performance difference between “EXEC (@sql)” and “EXEC sp_executesql @sql” for a frequently executed query.
For application code, I tend to lean on sp_executesql very heavily to create parameterized queries.