Ich habe zwei gespeicherte Prozeduren. Dieser ist unglaublich schnell (~ 2 Sekunden)
CREATE PROCEDURE [schema].[Test_fast]
@week date
AS
BEGIN
declare @myweek date = @week
select distinct serial
from [schema].[tEventlog] as e
join [schema].tEventlogSourceName as s on s.ID = e.FKSourceName
where s.SourceName = 'source_name'
and (e.EventCode = 1 or e.EventCode = 9)
and cast(@myweek as datetime2(3)) <= [Date]
and [Date] < dateadd(day, 7, cast(@myweek as datetime2(3)))
END
Und dieser läuft langsam (~ 2 Stunden):
create PROCEDURE [schema].[Test_slow]
@week date
AS
BEGIN
select distinct serial
from [schema].[tEventlog] as e
join [schema].tEventlogSourceName as s on s.ID = e.FKSourceName
where s.SourceName = 'source_name'
and (e.EventCode = 1 or e.EventCode = 9)
and cast(@week as datetime2(3)) <= [Date]
and [Date] < dateadd(day, 7, cast(@week as datetime2(3)))
END
Der einzige wirkliche Unterschied ist die Zeile (unter Verwendung der lokalen Variablen @myweek):
declare @myweek date = @week
Hier sind die Ausführungspläne. Der erste Plan stammt aus [Schema]. [Test_fast] und der zweite aus [Schema]. [Test_slow]:
Meine Frage lautet: Warum erhält SQL Server 2012 einen viel besseren Ausführungsplan (schneller), wenn ich den Parameter in einer lokalen Variablen speichere und dann diese lokale Variable verwende. Ist etwas mit der Statistik oder den Indizes kaputt? (Ich frage mich auch, warum der zweite Ausführungsplan keine parallele Ausführung verwendet).
UPDATE :
Ich gebe den 2 SPs den gleichen Parameter und starte sie zur gleichen Zeit (fast 2s Zeitunterschied). Dies ist keine automatische Aktualisierung der Statistik in dieser Datenbank.
Beispiel:
EXEC [schema].[Test_fast]
@week = '2016-02-08'
EXEC [schema].[Test_slow]
@week = '2016-02-08'
Hier ist der Ausführungsplan:
https://gist.github.com/anonymous/6e404f896d9613c2061a#file-sp_execution_plan-sqlplan
Eine zusätzliche Aktualisierung des Index hat ebenfalls keine Auswirkung.