Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Mesma consulta - planos de execução diferentes


A consulta 2 usa uma variável.

No momento em que o lote é compilado, o SQL Server não sabe o valor da variável, então apenas recorre a heurísticas muito semelhantes a OPTIMIZE FOR (UNKNOWN)

Para > ele assumirá que 30% das linhas acabarão correspondendo (ou 3.000 linhas em seus dados de exemplo). Isso pode ser visto na imagem do plano de execução abaixo. Isso está significativamente acima das 12 linhas (0,12%), que é o ponto de inflexão para esta consulta se ela usa uma varredura de índice clusterizado ou uma busca de índice não clusterizado e pesquisas de chave.

Você precisaria usar OPTION (RECOMPILE) para que ele leve em consideração o valor real da variável, conforme mostrado no terceiro plano abaixo.


Script

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