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!
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
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.
Je m'attendrais à ce que WHERE CellRow in (4, 5)
fonctionne mieux que WHERE CellRow > 3
. ----