在程序中添加标准会导致性能下降

时间:2016-10-21 18:33:27

标签: sql sql-server stored-procedures

我有一个函数fncDeptInfo。它目前在一秒钟内返回约1000条记录:

ALTER FUNCTION [dbo].[fncDeptInfo]()
RETURNS TABLE 
AS
RETURN 
(
    SELECT 
        tblContacts.Contact, 
        CASE tblContacts.Parent1
            WHEN 1900 THEN 0 
            WHEN 1901 THEN 1
            WHEN 1902 THEN 2
            WHEN 1903 THEN 3
            WHEN 1904 THEN 4
            WHEN 1905 THEN 5
            WHEN 1906 THEN 6
            ELSE NULL 
        END AS PRArea,
        DISTRICT.Contact AS DistrictID
    FROM 
        tblContacts 
    LEFT OUTER JOIN
        tblContacts AS DISTRICT ON tblContacts.Parent2 = DISTRICT.Contact 
    WHERE    
        (tblContacts.ContactType = 'Fire') AND
        (tblContacts.SubType = 'Dept')
)

我有一个调用此函数的过程:

SELECT  
    fncDeptInfo.Contact, DEPTPAID.CurPaid, 
    fncDeptInfo.PRArea, fncDeptInfo.DistrictID              
FROM    
    fncDeptInfo() AS fncDeptInfo 
INNER JOIN
    (SELECT 
         v_Item.BillToContact AS Contact,
         SUM(CASE WHEN Expiration = @Date1 AND tblProgramCodes.FormatCode = 'Membership' THEN 1 ELSE 0 END) AS CurPaid
     FROM 
         v_Item 
     INNER JOIN
         tblProgramCodes ON v_Item.ProgramCodeID = tblProgramCodes.ProgramCode 
     GROUP BY 
         v_Item.BillToContact) DEPTPAID ON fncDeptInfo.Contact = DEPTPAID.Contact
WHERE 
    (fncDeptInfo.PRArea > 0) AND (fncDeptInfo.DistrictID > 0) 
ORDER BY 
    fncDeptInfo.Contact

v_Item是一个非常复杂的视图,可以在多个不同的表中汇总财务记录。它返回超过300,000行。设计的程序在5秒内返回。

如果我添加这篇文章以获取fncDeptInfo的主要信息,则该过程需要一分半钟。但fncDeptInfo本身仍然会在大约一秒钟内返回:

LEFT OUTER JOIN fncEmployee(GETDATE(), 'Chief') AS CHIEF 
  ON tblContacts.Contact = CHIEF.Contact2 

如果我将此标准添加到程序中,现在也需要一分半钟。但是,如果我从过程中删除fncDeptInfo,它会在大约5秒内再次返回:

WHERE CurPaid > 0

我的猜测是视图在两种情况下都以某种方式被涉及并且被反复调用。有人可以建议一种更好的方法来设计它,以便性能不受影响吗?

1 个答案:

答案 0 :(得分:1)

一个简单的选择是将您的视图选择到临时表中,这可以防止重复调用视图。像

这样的东西
IF Object_ID ('tempdb..vitem_tmp') is not null DROP TABLE #vitem_tmp

SELECT *
INTO #vitem_tmp
FROM v_Item

[Your query, referencing #vitem_tmp instead of v_Item]