Я провел несколько тестов с длительной логикой, с одним и тем же битом кода (длинным оператором SELECT), работающим как в табличной функции, так и в хранимой процедуре, а также в прямом EXEC / SELECT, и все они выполнялись идентично.
На мой взгляд, для возврата результирующего набора всегда используйте табличную функцию, а не хранимую процедуру, поскольку это делает логику намного более простой и читаемой в запросах, которые впоследствии присоединяются к ним, и позволяет повторно использовать ту же логику. Чтобы избежать слишком большого снижения производительности, я часто использую «необязательные» параметры (т.е. вы можете передать им NULL), чтобы функция могла быстрее возвращать набор результатов, например:
CREATE FUNCTION dbo.getSitePermissions(@RegionID int, @optPersonID int, optSiteID int)
AS
RETURN
SELECT DISTINCT SiteID, PersonID
FROM dbo.SiteViewPermissions
WHERE (@optPersonID IS NULL OR @optPersonID = PersonID)
AND (@optSiteID IS NULL OR @optSiteID = SiteID)
AND @RegionID = RegionID
Таким образом, вы можете использовать эту функцию для множества различных ситуаций и не сильно снизите производительность. Я считаю, что это более эффективно, чем последующая фильтрация:
SELECT * FROM dbo.getSitePermissions(@RegionID) WHERE SiteID = 1
Я использовал эту технику в нескольких функциях, иногда с длинным списком «необязательных» параметров этого типа.