Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Gleiche Abfrage – unterschiedliche Ausführungspläne

Abfrage 2 verwendet eine Variable.

Zum Zeitpunkt der Kompilierung des Stapels kennt SQL Server den Wert der Variablen nicht und greift daher auf Heuristiken zurück, die OPTIMIZE FOR (UNKNOWN) sehr ähnlich sind

Für > Es wird davon ausgegangen, dass 30 % der Zeilen übereinstimmen (oder 3000 Zeilen in Ihren Beispieldaten). Dies ist im Bild des Ausführungsplans unten zu sehen. Dies ist deutlich mehr als die 12 Zeilen (0,12 %), was der Wendepunkt für diese Abfrage, ob sie einen Clustered-Index-Scan oder eine Nicht-Clustered-Index-Suche und Schlüsselsuche verwendet.

Sie müssten OPTION (RECOMPILE) verwenden um den tatsächlichen Variablenwert zu berücksichtigen, wie im dritten Plan unten gezeigt.

Skript

CREATE TABLE #Sale
(
    SaleId INT IDENTITY(1, 1)
        CONSTRAINT PK_Sale PRIMARY KEY,
    Test1 VARCHAR(10) NULL,
    RowVersion rowversion NOT NULL
        CONSTRAINT UQ_Sale_RowVersion UNIQUE
)

/*A better way of populating the table!*/
INSERT INTO #Sale (Test1)
SELECT TOP 10000 NULL 
FROM master..spt_values v1, master..spt_values v2

GO

SELECT *
FROM #Sale
WHERE RowVersion > 0x000000000001C310-- Query #1


DECLARE @LastVersion rowversion = 0x000000000001C310

SELECT *
FROM #Sale
WHERE RowVersion > @LastVersion-- Query #2


SELECT *
FROM #Sale
WHERE RowVersion > @LastVersion
OPTION (RECOMPILE)-- Query #3

DROP TABLE #Sale