我有一个函数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
我的猜测是视图在两种情况下都以某种方式被涉及并且被反复调用。有人可以建议一种更好的方法来设计它,以便性能不受影响吗?
答案 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]