web-dev-qa-db-fra.com

Dois-je utiliser de nombreux index à champ unique au lieu d'index multi-colonnes spécifiques?

Cette question concerne l'efficacité d'une technique d'indexation SQL Server. Je pense qu'il est connu comme "intersection d'index".

Je travaille avec une application SQL Server (2008) existante qui présente un certain nombre de problèmes de performances et de stabilité. Les développeurs ont fait des choses étranges avec l'indexation. Je n'ai pas été en mesure d'obtenir des références concluantes sur ces problèmes, et je ne trouve aucune documentation vraiment bonne sur les internets.

Il existe de nombreuses colonnes consultables sur une table. Les développeurs ont créé un index de colonne unique sur CHAQUE des colonnes consultables. La théorie était que SQL Server serait capable de combiner (intersecter) chacun de ces index pour accéder efficacement à la table dans la plupart circonstances. Voici un exemple simplifié (la vraie table a plus de champs):

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, ...

CREATE NONCLUSTERED INDEX [IndexCol1] ON [dbo].[FatTable]  ( [col1] ASC )
CREATE NONCLUSTERED INDEX [IndexCol2] ON [dbo].[FatTable] ( [col2] ASC )

select * from fattable where col1 = '2004IN' 
select * from fattable where col1 = '2004IN' and col2 = 4

Je pense que plusieurs index de colonnes ciblés sur des critères de recherche sont bien meilleurs, mais je peux me tromper. J'ai vu des plans de requête qui montrent que SQL Server fait une correspondance de hachage sur deux recherches d'index. Peut-être que cela a du sens lorsque vous ne savez pas comment la table est recherchée? Merci.

36
RaoulRubin

Ce dont vous avez besoin sont couvrant les index, c'est-à-dire. index pouvant satisfaire une requête par eux-mêmes. Mais un index "couvrant" a un problème: il couvre une requête spécifique . Donc, pour développer une bonne stratégie d'indexation, vous devez comprendre votre charge de travail: quelles requêtes atteignent la base de données, lesquelles sont critiques et lesquelles le sont non, combien de fois chaque type de requête est exécuté, etc etc etc. Si cela semble compliqué, c'est parce que c'est compliqué.

Cependant, vous pouvez appliquer certaines règles générales. Le MSDN couvre assez bien les bases:

Il existe également une myriade d'articles apportés par la communauté, par exemple. Enregistrement Webcast - DBA Darwin Awards: Index Edition .

Et pour répondre spécifiquement à votre question: des index séparés sur chaque colonne peuvent fonctionner, à condition que chaque colonne ait une haute sélectivité (plusieurs valeurs distinctes, chaque valeur n'apparaissant que quelques fois dans la base de données). Le plan d'accès résultant utilisant la jointure par hachage entre deux analyses de plage d'index fonctionne généralement très bien. Les colonnes avec une faible sélectivité (peu de valeurs distinctes, chaque valeur apparaissant plusieurs fois dans la base de données) n'ont aucun sens d'être indexées seules, l'optimiseur de requête les ignorera simplement. Cependant, les colonnes à faible sélectivité font souvent de bonnes clés composites lorsqu'elles sont associées à une colonne à haute sélectivité.

39
Remus Rusanu