Deze tests (database AdventureWorks2008R2) laten zien wat er gebeurt:
SET NOCOUNT ON;
SET STATISTICS IO ON;
PRINT 'Test #1';
SELECT p.BusinessEntityID, p.LastName
FROM Person.Person p
WHERE p.LastName LIKE '%be%';
PRINT 'Test #2';
DECLARE @Pattern NVARCHAR(50);
SET @Pattern=N'%be%';
SELECT p.BusinessEntityID, p.LastName
FROM Person.Person p
WHERE p.LastName LIKE @Pattern;
SET STATISTICS IO OFF;
SET NOCOUNT OFF;
Resultaten:
Test #1
Table 'Person'. Scan count 1, logical reads 106
Test #2
Table 'Person'. Scan count 1, logical reads 106
De resultaten van SET STATISTICS IO
laat zien dat LIO hetzelfde is .Maar de uitvoeringsplannen zijn heel anders:
In de eerste test gebruikt SQL Server een Index Scan
expliciet, maar in de tweede test gebruikt SQL Server een Index Seek
dat is een Index Seek - range scan
. In het laatste geval gebruikt SQL Server een Compute Scalar
operator om deze waarden te genereren
[Expr1005] = Scalar Operator(LikeRangeStart([@Pattern])),
[Expr1006] = Scalar Operator(LikeRangeEnd([@Pattern])),
[Expr1007] = Scalar Operator(LikeRangeInfo([@Pattern]))
en, de Index Seek
operator gebruikt een Seek Predicate
(geoptimaliseerd) voor een range scan
(LastName > LikeRangeStart AND LastName < LikeRangeEnd
) plus nog een niet-geoptimaliseerd Predicate
(LastName LIKE @pattern
).
Mijn antwoord:het is geen "echte" Index Seek
. Het is een Index Seek - range scan
die in dit geval dezelfde prestaties heeft als Index Scan
.
Zie ook het verschil tussen Index Seek
en Index Scan
(vergelijkbaar debat):Dus...is het een zoekactie of een scan?
.
Bewerken 1: Het uitvoeringsplan voor OPTION(RECOMPILE)
(zie de aanbeveling van Aaron aub) toont ook een Index Scan
(in plaats van Index Seek
):