Cette question concerne les performances de l'index SQL Server avec un varchar(2000)
comme un INCLUDE
dans un index de couverture.
J'essaie d'améliorer les performances dans une application de base de données lente et instable. Dans certains cas, les données sont accessibles par les grandes chaînes de varchar, avec les requêtes , y compris les opérations de chaîne multple comme SUBSTRING()
, SPACE()
et DATALENGTH()
. Voici un exemple simplifié d'accès;
update fattable set col3 =
SUBSTRING(col3,1,10) + '*' +
SUBSTRING(col3,12,DATALENGTH(col3)-12)
from fattable where substring(col3,10,1) = 'A' and col2 = 2
Le schéma ressemble à ceci:
CREATE TABLE [dbo].[FatTable](
[id] [bigint] IDENTITY(1,1) NOT NULL,
[col1] [nchar](12) NOT NULL,
[col2] [int] NOT NULL,
[col3] [varchar](2000) NOT NULL, ...
L'index suivant a été défini, avec un champ couvrant sur la grande colonne de texte.
CREATE NONCLUSTERED INDEX [IndexCol2Col3] ON [dbo].[FatTable] ( [col2] ASC )
INCLUDE( [col3] )
D'après ce que j'ai lu, c'est MAUVAIS de mettre de grands champs de données dans un index. J'ai lu plusieurs articles, dont http://msdn.microsoft.com/en-us/library/ms190806.aspx qui discutent de l'impact de la pagination et de la taille du disque sur les performances de l'index. Cela étant dit, le plan de requête utilise définitivement l'index de couverture. Je n'ai pas suffisamment d'informations pour déterminer combien cela me coûte réellement en termes de charge système. Je sais que dans l'ensemble, le système fonctionne mal et je crains que ce soit l'un des problèmes. Des questions:
Mettre cette
varchar(2000)
colonne dans l'indexINCLUDE
est-il une bonne idée?Étant donné que les
INCLUDE
champs sont stockés dans des nœuds feuilles, ont-ils beaucoup de performances d'index d'impact?
Mise à jour: Merci pour les excellentes réponses! C'est une question injuste à certains égards - comme vous le dites, il n'y a pas de bonne réponse absolue sans statistiques et profilage réels. Comme tant de problèmes de performances, je suppose que la réponse est "cela dépend".
la source
VARCHAR(2000)
qui ne stocke généralement que dix caractères est une chose; un solide 2000 octets par enregistrement est autre chose.Réponses:
Ever est un grand mot, mais, en général, non, je ne mettrais pas un champ varchar (2000) dans un INCLUDE.
Et oui, la façon dont les données sont stockées au niveau de la page peut sérieusement affecter les performances de l'index, selon la façon dont l'index est utilisé.
Le fait est que plus vous pouvez insérer de lignes de données dans une page, moins vous devez accéder à des pages, plus votre système est rapide, pour la plupart. L'ajout d'une colonne très volumineuse signifie moins d'informations stockées sur une page.Par conséquent, en cas de recherche ou de numérisation de plage, davantage de pages doivent être lues pour récupérer les données, ce qui ralentit considérablement les choses.
Pour savoir avec certitude s'il s'agit d'un problème sur votre requête ou sur votre système, vous devez surveiller les lectures, en particulier le nombre de pages utilisées par la requête.
la source
Pouvez-vous revoir la clé d'index en cluster actuelle et peut-être créer
col2
la clé d'index en cluster à la place? De cette façon, vous obtenez le comportement «inclure» de la couverture (puisque les indices groupés incluent toujours «tout») sans dupliquer les données. Ceci, bien sûr, est sujet à de nombreuxif
etbut
, peut-être, mérite néanmoins d'être considéré. Bien sûr, si l'index cluster actuel applique une contrainte (clé primaire, unique), cette contrainte devra être déplacée dans un index non cluster.la source
Il est difficile de répondre. Tout dépendra de votre rapport lecture / écriture. Avez-vous testé une charge de travail ou simulé un cycle commercial complet sur un système de test, avec et sans la colonne incluse? La recherche sans cela peut coûter cher, mais si vous mettez à jour les données plus souvent que vous ne les lisez, cela pourrait être correct.
la source
VARCHAR(2000)
colonne, ou dépannez-vous les performances d'une requête très spécifique qui ne représente pas la plupart des requêtes? Comme Grant le suggère si cette colonne n'est pas utilisée dans un grand nombre de requêtes, ou cause vraiment des problèmes pour les recherches, il sera probablement préférable de payer le prix de la recherche lorsque vous en avez besoin, mais de ne pas payer le stockage lorsque vous ne le faites pas. . Encore une fois, il est vraiment difficile de dire de quel côté de la clôture vous devriez être, car nous n'avons pas vraiment de détails (et encore plus difficile parce que vous ne pouvez pas tester - vous devriez vous efforcer de résoudre ce problème).Je sais que je suis en retard pour cette fête, mais j'indexerais exactement les expressions utilisées pour localiser les lignes, telles que la sous-chaîne (col3,10,1). Si le col3 entier est utilisé, j'indexerais CHECKSUM (col3) (en comprenant bien sûr qu'il pourrait y avoir des collisions).
la source