2010-07-12 6 views
3
declare @name varchar(156) 
set @name ='sara' 
--Query 1: 
SELECT [PNAME] FROM [tbltest] where [PNAME] like '%'[email protected]+'%' 

--Query 2: 
SELECT [PNAME] FROM [tbltest] where [PNAME] like '%sara%' 

supposons qu'il existe un index NoneClustered sur la colonne [PNAME] de [tbltest]. lors de l'exécution des requêtes, plan d'exécution Voir l'index Recherche pour l'interrogation 1 et l'index recherche pour l'interrogation 2. Je m'attendais à ce que Excution Paln Show Index Scan Pour les deux requêtes, mais en raison de l'utilisation du paramètre dans la première requête. Alors qu'est-ce que je la mater? dans les deux requêtes, nous avons utilisé '%' à l'autre côté, et sachez que dans cet état, sql ne considère pas l'index mais pourquoi en premier Query Excution Plan Show Index Seek? merciSql Le plan d'exécution affiche un résultat différent pour les mêmes entrées

Répondre

0

Si vous utilisez DBCC SHOW_STATISTICS sur votre table et l'index utilisé, recherchez "String Index = YES" dans la première ligne de la sortie. SQL Server gère certaines sorte de statistiques supplémentaires pour satisfaire les requêtes comme '% x'

Dans la première requête, vous verrez probablement des valeurs scalaires calculées - regardez dans le plan de requête pour LikeRangeStart ('%' + @ name + '% '). L'index de recherche est contre ces valeurs par opposition à l'analyse d'index contre% sara%.

Comment cela fonctionne je ne sais pas. Pourquoi SQL Server ne serait pas assez intelligent pour convertir 'sara' en une constante et faire la requête de la même manière que je ne connais pas non plus. Mais je pense que c'est ce qui se passe.

Contre% sara% effectue une analyse d'index, en lisant l'index entier. Contre% + @ name +%, il crée des valeurs calculées RangeStart/RangeEnd/RangeInfo et les utilise pour faire une recherche d'index en tirant profit des statistiques de chaînes supplémentaires.

0

Je pense que Mike est sur la bonne voie pour savoir si vous allez ou non sur l'index. Votre suivi concernant les coûts pourrait nécessiter une meilleure compréhension de la façon dont vos données sont distribuées dans le tableau. J'ai vu des cas où frapper un index est plus coûteux en raison de la nécessité de deux lectures de disque. Pour comprendre pourquoi, vous devez savoir comment vos données sont réparties dans l'index, combien d'enregistrements peuvent tenir dans une page et quel est votre schéma de mise en cache.

Je dirais qu'il peut être difficile de régler une requête avec un% en tête. La base de données devra traverser complètement votre index (ou table) et toucher chaque nœud à la recherche d'une valeur contenant "sara". En fonction de vos besoins, vous pouvez envisager une recherche en texte intégral (c'est-à-dire que la valeur du paramètre dans cette requête est utilisée car elle est fournie en entrée par un utilisateur de votre application).

1

Lorsque vous utilisez un paramètre, interrogez 2 une constante.

Le plan de la requête 2 ne sera pas réutilisé si vous modifiez la valeur de la constante.

La requête pour le plan 1 peut être. Dans ce cas, SQL Server (simplement) laisse ses options ouvertes pour réutiliser le plan.

AKA: les requêtes sont et non de même. Si vous force parameterisation, alors vous devriez faire les deux requêtes comme la requête 1. Mais je n'ai pas essayé ...

Questions connexes