Realicé algunas pruebas con un largo tiempo de lógica, con el mismo bit de código (una instrucción SELECT larga) que se ejecuta en una función con valores de tabla y un procedimiento almacenado, y un EXEC/SELECT directo, y cada uno se realiza de forma idéntica.
En mi opinión utilice siempre una función de valores de tabla en lugar de un procedimiento almacenado para devolver un conjunto de resultados, ya que hace la lógica mucho más fácil y legible en las consultas que posteriormente se unen a ellos, y le permite reutilizar la misma lógica. Para evitar el exceso de un impacto en el rendimiento, que a menudo utilizan los parámetros "opcionales" (es decir, se puede pasar NULL a ellos) para activar la función para devolver el conjunto de resultados a ser más rápido, por ejemplo:
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
De esta manera usted puede usar esta función para muchas situaciones diferentes y no da un gran golpe de rendimiento.Creo que esto es más eficiente que la filtración después:
SELECT * FROM dbo.getSitePermissions(@RegionID) WHERE SiteID = 1
he utilizado esta técnica en varias funciones, a veces con una larga lista de parámetros "opcionales" de este tipo.
Esta parece ser la respuesta perfecta: http://stackoverflow.com/a/1179778/365188 –