MS SQL SELECT WHERE @Variable --> Laufzeit

Squicky

Lt. Commander
Dabei seit
Sep. 2002
Beiträge
1.349
Hallo

Folgende Situation:
Benutzt wird Microsoft SQL Server 2012.
Eine Tabelle (tab) hat 8 Spalten (sp1, sp2, …, sp8) und ca. 2.000.000 Zeilen.
„sp1“ ist von Typ „INT“.

Variante 1:
Code:
SELECT sp1, sp2, sp3, sp4
FROM tab
WHERE sp1 = 0
Variante 2:
Code:
DECLARE @x INT
SET @x = 0

SELECT sp1, sp2, sp3, sp4
FROM tab
WHERE sp1 = @x
Beide Varianten bringen das gleiche Ergebnis zurück (7 Zeilen).
Variante 1 braucht dafür (deutlich) weniger wie 1 Sekunde.
Variante 2 braucht dafür ca. 20 Sekunden.

Warum genau braucht Variante 2 so viel Zeit?

P.S.: Hier ist ein „dirty workaround“:
Variante 3:
Code:
DECLARE @x INT
SET @x = 0

DECLARE @s NVARCHAR(MAX)
SET @s = '
SELECT sp1, sp2, sp3, sp4
FROM tab
WHERE sp1 = ' + CAST(@x AS NVARCHAR(MAX))

EXEC(@s)
Variante 3 braucht ebenfalls wie Variante 1 (deutlich) weniger wie 1 Sekunde.

Warum "genau" braucht Variante 2 so viel Zeit?

Danke
 

Ehomer

Cadet 4th Year
Dabei seit
Juli 2011
Beiträge
99
Was sagt denn der Ausführungsplan im SQL Server Management Studio zu den jeweiligen Prozeduren?

Frage 2: sind alle Spalten die du in deinem WHERE verwendest indexiert?
 
Zuletzt bearbeitet:

Squicky

Lt. Commander
Ersteller dieses Themas
Dabei seit
Sep. 2002
Beiträge
1.349
Was sagt denn der Ausführungsplan im SQL Server Management Studio zu den jeweiligen Prozeduren?

Frage 2: sind alle Spalten die du in deinem WHERE verwendest indexiert?
Hallo

Ein Index ist auf der Spalte sp1 vorhanden.

Warum sollte dies aber einen Unterschied machen?
In Variante 1 und Variante 2 werden die selben Spalten angezeicht und es wird nach der selben Spalte per WHERE gefiltert.

(Ausführungsplan kann ich erst in ein paar Tagen testen.)
 

Nai

Lt. Commander
Dabei seit
Aug. 2012
Beiträge
1.531

AlbertLast

Lieutenant
Dabei seit
Juni 2002
Beiträge
715
Das ist das Standard verhalten von Datenbanken(egal ob ms,my,pg usw),
wenn sie ein prepared statement haben.

Ohne Ausführungsplan kann man da nicht mehr dazu sagen.
 

nittels

Ensign
Dabei seit
Nov. 2013
Beiträge
164
Bei mir funktioniert das tadellos. Egal welche Variante ich anwende, es wird immer schön der Index benutzt und das Query ist in ein paar ms durch.

Dein Ausführungsplan wird vermutlich zeigen, dass bei Variante 1 und 3 der Index benutzt wird, während er bei Variante 2 einen Full Table Scan hinlegt und den Index ignoriert. Das kann aber mehrere Gründe haben.

Einer wäre, dass der Plan für Variante 2 auf einem nicht selectiven Query basiert, in dem er sich entschieden hat den Index zu ignorieren da er sowieso von einer großen Range ausgeht und den Plan dann auch bei selectiven Parametern anwendet. Immerhin ist die abgefragte Spalte nicht unique, also ist die Möglichkeit gegeben.

Die Antwort steht eigentlich eh schon im verlinkten Artikel; einen Query- bzw. Index Hint mit angeben. Ist zwar ne Methode mim Hammer, aber wenn alle Stricke reißen kanns helfen. Du könntest auch ne Stored Procedure basteln und mit RECOMPILE oder OPTIMIZE FOR arbeiten.
 
Zuletzt bearbeitet:
Top