Mam procedura składowana, która może uzyskać dane z 2 różnych źródeł w zależności od tego, czy użytkownik żąda danych z jednego zamkniętego okresu (zarchiwizowane w tabeli hurtowni danych) lub z okresu otwartego (dane z transakcji tabele).SQL IF Wydanie wydajności ELSE
Jeśli przekazuję parametry, które ograniczają wybór do tabeli hurtowni danych (podając rok i okres dla okresu zamkniętego), procedura zwraca bardzo dużo czasu, chyba że skomentuję kod ELSE BEGIN .... Żadne dane nie pochodzą z części kodu ELSE, ale nadal spowalnia procedurę. Jeśli skomentuję część kodu ELSE, jest ona bardzo szybka.
Próbowałem OPTION (RECOMPILE)
i używam zmiennych lokalnych, aby uniknąć sniffing parametru, ale to nie pomaga. Czy istnieje sposób na obejście tego? Poniżej jest przykład tego, co robię, że działa wolno:
IF @Year <> 0 AND @Period <> 0 AND (SELECT PerClosedTimestamp
FROM Period
WHERE
PerCompanyID = @CompanyID AND
PerYear = @Year AND
PerPeriod = @Period) IS NOT NULL
BEGIN
SELECT
datawhse.column1, datawhse.column2, etc …
FROM
datawhse
END
ELSE
BEGIN
SELECT
trantable.column1, trantable.column2, etc…
FROM
trantable
END
Gdybym wyklucza instrukcja else biegnie bardzo szybko:
IF @Year <> 0
AND @Period <> 0
AND (SELECT PerClosedTimestamp
FROM Period
WHERE PerCompanyID = @CompanyID
AND PerYear = @Year
AND PerPeriod = @Period) IS NOT NULL
BEGIN
SELECT datawhse.column1
,datawhse.column2, etc …
FROM datawhse
END
Nie jest to odpowiedź, ale interesujący i powiązany (nie duplikat) post http://dba.stackexchange.com/questions/9835/using-if-in-t-sql-weakens-or-breaks-execution-plan- buforowanie – scsimon
co, jeśli dodasz TOP 1 przed "PerClosedTimestamp" lub użyjesz EXISTS. Spróbuj również zmienić warunki na IF Rok = 0 lub Okres = 0 lub (wybierz ...) jest pusty, następnie wykonaj drugi blok, ELSE wykonaj pierwszy. Spróbuj również umieścić "WHERE Year = 0 or Period = 0" (przez powielenie warunku) w drugim bloku. – Anton
Byłoby miło zobaczyć plany zapytań dla powolnych i szybkich egzekucji. –