Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Comment LIKE '%...' peut-il rechercher sur un index ?

Ces tests (base de données AdventureWorks2008R2) montrent ce qui se passe :

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;

Résultats :

Test #1
Table 'Person'. Scan count 1, logical reads 106
Test #2
Table 'Person'. Scan count 1, logical reads 106

Les résultats de SET STATISTICS IO montre que LIO est le même .Mais les plans d'exécution sont assez différents :

Dans le premier test, SQL Server utilise un Index Scan explicite mais dans le second test SQL Server utilise un Index Seek qui est un Index Seek - range scan . Dans le dernier cas, SQL Server utilise un Compute Scalar opérateur pour générer ces valeurs

[Expr1005] = Scalar Operator(LikeRangeStart([@Pattern])), 
[Expr1006] = Scalar Operator(LikeRangeEnd([@Pattern])), 
[Expr1007] = Scalar Operator(LikeRangeInfo([@Pattern]))

et, le Index Seek l'opérateur utilise un Seek Predicate (optimisé) pour un range scan (LastName > LikeRangeStart AND LastName < LikeRangeEnd ) plus un autre Predicate non optimisé (LastName LIKE @pattern ).

Ma réponse :ce n'est pas un "vrai" Index Seek . C'est un Index Seek - range scan qui, dans ce cas, a les mêmes performances que Index Scan .

Veuillez également voir la différence entre Index Seek et Index Scan (débat similaire):Alors... est-ce une recherche ou une analyse ? .

Modification 1 : Le plan d'exécution pour OPTION(RECOMPILE) (voir la recommandation d'Aaron s'il vous plaît) montre également un Index Scan (au lieu de Index Seek ):