Ich habe eine Funktion fncDeptInfo. Derzeit werden in weniger als einer Sekunde etwa 1000 Datensätze zurückgegeben:
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')
)
Ich habe eine Prozedur, die diese Funktion unten aufruft:
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
ist eine sehr komplexe Ansicht, die Finanzaufzeichnungen über viele verschiedene Tabellen hinweg zusammenfasst. Es werden über 300.000 Zeilen zurückgegeben. Der geplante Vorgang kehrt in 5 Sekunden zurück.
Wenn ich dieses Stück hinzufüge, um die Hauptinformationen zu fncDeptInfo zu erhalten, dauert der Vorgang anderthalb Minuten. Aber fncDeptInfo alleine kehrt immer noch in ungefähr einer Sekunde zurück:
LEFT OUTER JOIN fncEmployee(GETDATE(), 'Chief') AS CHIEF
ON tblContacts.Contact = CHIEF.Contact2
Wenn ich dieses Kriterium zum Verfahren hinzufüge, dauert es jetzt auch anderthalb Minuten. Wenn ich jedoch fncDeptInfo aus der Prozedur entferne, kehrt es in etwa 5 Sekunden wieder zurück:
WHERE CurPaid > 0
Ich vermute, dass die Ansicht in beiden Fällen irgendwie involviert ist und wiederholt aufgerufen wird. Kann jemand einen besseren Weg vorschlagen, dies so zu gestalten, dass die Leistung nicht leidet?
Eine einfache Option besteht darin, Ihre Ansicht in einer temporären Tabelle auszuwählen, wodurch der wiederholte Aufruf der Ansicht verhindert wird. Etwas wie
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]
Dieser Artikel stammt aus dem Internet. Bitte geben Sie beim Nachdruck die Quelle an.
Bei Verstößen wenden Sie sich bitte [email protected] Löschen.
Lass mich ein paar Worte sagen