sql >> Database >  >> RDS >> Sqlserver

Hoe kan LIKE '%...' zoeken op een index?

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 ):




  1. Express-query voor SQL

  2. java.io.IOException:Illegale UTF-8-reeks:initiële byte is 11111xxx:252 - Eclipse en PostgreSQL

  3. Oracle naar SQL2005 DATETIME-veld loopt over in SSIS

  4. $_SESSION variabelen worden niet opgeslagen wanneer automatisch ingelogd