web-dev-qa-db-fra.com

Comment éviter les analyses d'index dans SQL Server 2005?

J'ai une table nommée Cell qui a des colonnes comme Cell_ID, CellValue et CellRow.

Cellrow peut avoir des valeurs maximum 1 à 5. Il existe un index en cluster sur Cell_Id champ. Cette table contient 100 000 lignes.

Dans ma requête, je dois utiliser la colonne CellRow de la clause WHERE comme CellRow > 3 Pour obtenir des données de CellValue champ. Le problème est que lorsque je le fais comme ça, il s'agit toujours d'une balayage de table qui rend la requête très lente.

Je l'ai également vérifiée en mettant l'indice non clusterné sur CellRow champ, mais numérisation d'indexage fixe car le champ CellRow n'a pas autant de valeurs, il n'a que 1 à 5 valeurs à chaque fois. Je ne peux pas utiliser CellID dans la clause WHERE.

J'utilise de nombreuses tables dans ma requête comme

Table_1 rejoint avec table_2 En utilisant une colonne d'index en cluster et table 2 rejoint avec table_3 En utilisant une colonne d'index non clustered et table_3 se joint à Cell table à l'aide de l'indice non en cluster.

L'histoire de fin est, je reçois des valeurs différentes de toutes les tableaux, y compris la table des cellules, mais lorsque j'utilise CellRow champ dans la clause O quelle que soit la clause d'index.

Toute solution :)

Merci beaucoup!

4
user999896

Toute solution :)

Non, pas vraiment.

Comme vous l'avez dit - CellRow _ n'est tout simplement pas très sélectif - 5 valeurs possibles, 100 000 rangées = environ 20 000 lignes pour chaque valeur possible.

L'optimiseur de requête de SQL Server reconnaît cela et probablement des chiffres, il est plus facile et plus efficace de faire une analyse index plutôt que d'une recherche pour 20 000 rangées.

Le seul moyen d'éviter que cela soit d'utiliser un index plus sélectif, c'est-à-dire une autre colonne qui sélectionne 2%, 3% ou max. 5% des lignes pour chaque requête.

PS: Vérifiez votre plan d'exécution - obtient-elle les valeurs directement à partir de l'index ou avez-vous besoin d'une étape "Recherche clé" pour aller obtenir les données ??

Vous n'avez pas mentionné quels types de données vos colonnes sont - si le CellValue n'est pas trop gros, vous pouvez l'ajouter à l'index (ou au moins l'inclure dans l'index) pour éviter les recherches de clé coûteuses:

CREATE INDEX IX_CellRow_CellValues
ON dbo.Cell(CellRow) INCLUDE(CellValue)

Vous auriez toujours l'analyse de l'index, bien que

11
marc_s

créez un index sur Cellrow, mais l'optimiseur peut décider de ne pas l'utiliser s'il ne dispose que de 5 valeurs, mais si vous savez que les valeurs supérieures à 3 sont rares, vous pouvez ajouter un indice à la requête à trier de faire utiliser le moteur à utiliser l'index. .
[.____] Edit: Une autre solution plus complexe qui peut ne pas fonctionner ou non pour vous, c'est de séparer les coordonnées dans des tables différentes et de créer une vue qui est l'union des tables pour les coordonnées 4 et 5, de cette façon lorsque vous interrogez cette vue sur cette vue. , il n'utilisera pas d'index, mais il ne traversera que les enregistrements impliqués. Ceci est un type de quels dictionnaires de données font, mais faites attention à cela, car cela implique plus de maintenance (par exemple, les données changent de 3 à 4, ce n'est plus une seule mise à jour, mais une suppression de la table '3' et d'insérer dans le tableau. '4', par exemple). En fin de compte, cela dépend de vos besoins. Habituellement, ce type de choses est fait lorsque vous parlez de millions d'enregistrements, mais vous pouvez essayer de voir si cela le fait pour vous.

0
Rodolfo

Je m'attendrais à ce que WHERE CellRow in (4, 5) fonctionne mieux que WHERE CellRow > 3. ----

0
David J. Davison