Pourquoi SQL Server n'utilise-t-il pas mon index?
Dans notre base de données nous avons cette table avec 200.000 lignes
CREATE TABLE dbo.UserTask (
UserTask_ID int NOT NULL IDENTITY (1, 1),
UserTask_SequenceNumber int NOT NULL DEFAULT 0,
UserTask_IdEntitat uniqueidentifier NOT NULL,
UserTask_Subject varchar(100) NOT NULL,
UserTask_Description varchar(500) NOT NULL,
.....
.....
CONSTRAINT [PK_UserTask] PRIMARY KEY CLUSTERED
(
[UserTask_ID] ASC
) ON [PRIMARY]
) ON [PRIMARY]
J'ai créé un index sur UserTask_IdEntitat
colonne avec
CREATE NONCLUSTERED INDEX IX_UserTask_IDEntitat ON dbo.UserTask
(
UserTask_IDEntitat
)
De l'exécution de la requête suivante, de l'exécution du plan nous montre que l'indice sur UserTask_IDEntitat
est utilisé pour faire la requête:
SELECT UserTask_ID
FROM UserTask
WHERE UserTask_IdEntitat = @IdEntitat
ORDER BY UserTask_LastSendSystemDateTime desc
Mais Si nous y ajoutons une autre colonne de la Select
liste, puis de l'index n'est pas utilisé
SELECT UserTask_ID, UserTask_SequenceNumber, UserTask_IDEntitat, ....., UserTask_Subject
FROM UserTask
WHERE UserTask_IdEntitat = @IdEntitat
ORDER BY UserTask_LastSendSystemDateTime desc
Pourquoi l'ajout d'une colonne différente de la clé primaire fait que le Serveur SQL plan d'exécution de ne pas utiliser l'index sur la UserTask_IDEntitat
de la colonne?
Suivant ce lien http://bytes.com/topic/sql-server/answers/144592-sqlsever-not-using-index il semble que le nombre de fois que la valeur filtrée est répété sur la colonne, Il peut le faire, que l'index n'est pas utilisé, mais j'ai essayé de faire la requête avec un @IdEntitat valeur qui est répété à 60.000 fois et d'autres qui se répète seulement 175 fois et les résultats sont les mêmes, l'index sur IDEntitat
colonne est ignorée.
Cela me rend fou!!!
Merci pour votre aide.
source d'informationauteur Marc Cals
Vous devez vous connecter pour publier un commentaire.
OK - aussi longtemps que vous sélectionnez uniquement la colonne qui est l'indice, ou quelque chose à partir de la clé de cluster (généralement, c'est la clé primaire), puis l'index sera utilisé, car SQL Server pouvez trouver toutes les informations dont il a besoin (le
UserTask_IDEntitat
colonne, et l'index en cluster colonne(s) ) au niveau de la feuille de l'index de la structure de navigation. Donc, il peut renvoyer les données nécessaires pour queSELECT
requête directement à partir de l'indice de feuilles de pages de niveau.Cependant: si vous avez besoin de sélectionner une deuxième colonne, c'est-à ni dans la définition de l'index, ni partie de la clé de cluster, puis SQL Server aurait à faire une soi-disant recherche de signet dans les pages de données.
Donc pour chaque ligne il trouve dans votre index non-cluster, il aurait à prendre le regroupement de l'indice de la valeur, de la recherche de l'index cluster de retrouver les données de la page au niveau de la feuille de l'index cluster, et puis choisir qu'une seule colonne que vous souhaitez.
Recherches signet sont grands pour les petits nombres de hits - ils sont totalement dévastateur pour les performances si vous êtes à la sélection de plusieurs milliers de lignes. Dans ce cas, l'optimiseur de requête SQL Server utilise correctement une analyse d'index cluster au lieu - depuis dans l'index cluster, sur le niveau de la feuille, il a toutes les lignes disponible immédiatement.
Donc: si vous avez un index sur
UserTask_IDEntitat
et que vous avez parfois besoin d'une deuxième colonneUserTask_SequenceNumber
trop - alors vous pourriez inclure cette colonne dans cet index non-cluster de la vôtre:Avec cette, colonne supplémentaire est présent dans le niveau feuille de l'index non-cluster (et il ne peut pas être utilisé dans un
WHERE
clause - il ne fait pas partie de la structure de navigation de l'index!) - et votre deuxièmeSELECT
peut encore être satisfaites à partir de la feuille au niveau des nœuds de l'index non-cluster -> pas cher signet recherches sont nécessaires -> votre index sera utilisé à nouveau.Longue histoire courte: à moins que votre index non-cluster est très sélective (par exemple, les rendements de 1% de vos lignes ou moins), et à moins que votre index non-cluster est un index de couverture (un index qui contient toutes les colonnes nécessaires pour satisfaire une requête particulière), les modifications sont assez haut que SQL Server PAS utilisez votre index non-cluster.
Pour plus d'informations:
Vous pouvez utiliser les indicateurs de requête dans la requête à faire usage de l'Index. Voici un lien pour plus de détails:
http://msdn.microsoft.com/en-us/library/ms181714.aspx