Notre projet gère une très grande base de données très compliquée. Il y a environ un mois, nous avons remarqué que l'espace utilisé par les colonnes indexées contenant des valeurs nulles devenait trop grand. En réponse à cela, j'ai écrit un script qui rechercherait dynamiquement tous les index à colonne unique contenant plus de 1% de valeurs nulles, puis supprimerait et recréerait ces index en tant qu'index filtrés à condition que la valeur ne soit PAS NUL. Cela supprimerait et recréerait des centaines d'index dans la base de données et libérerait généralement près de 15% de l'espace utilisé par l'ensemble de la base de données.
Maintenant, j'ai deux questions à ce sujet:
A) Quels sont les inconvénients de l'utilisation d'index filtrés de cette manière? Je suppose que cela ne ferait qu'améliorer les performances, mais y a-t-il des risques de performances impliqués?
B) Nous avons reçu des erreurs ( 'impossible de supprimer l'index XYZ car il n'existe pas ou vous n'avez pas la permission' ) lors de la suppression et de la recréation des index, même si, après vérification, tout s'est déroulé exactement comme prévu. Comment cela peut-il arriver?
Merci pour toute aide!
Edit: En réponse à @Thomas Kejser
Salut et merci, mais il s'est avéré que c'était un désastre. À l'époque, nous ne comprenions pas plusieurs choses telles que:
- Lors d'une requête, SQLOS crée des plans d'index avant de déterminer qu'il ne peut pas utiliser de valeurs NULL pour joindre des colonnes de table. IE, vous avez vraiment besoin d'un filtre de clause WHERE ajustant l'index pour chaque index filtré utilisé dans la requête, sinon l'index ne sera pas utilisé du tout.
- La suppression et la création d'index et la mise à jour redondante de leurs statistiques une fois de plus par la suite peuvent ne pas suffire pour produire les plans mis à jour, ce que nous supposions. Il semble que dans certains cas, seule une charge de travail suffisamment élevée obligera SQL Server à réévaluer les plans.
- Il existe des éléments exotiques dans la fonctionnalité du planificateur d'exécution qui sont difficiles à déterminer par le seul bon sens et la seule logique. Avec des milliers de variations générées par le code de différentes requêtes, des index apparemment inutiles peuvent aider dans certaines statistiques et plans de requête qui finissent par être utilisés dans des requêtes critiques.
Finalement, ces changements ont été annulés. Les index filtrés sont donc un outil puissant, mais vous devez vraiment comprendre exactement quelles données sont extraites de ces colonnes. Là où les index normaux mis à part les problèmes d'espace sont plutôt faciles à appliquer, les index filtrés représentent des solutions très personnalisées. Ils ne remplacent certainement pas un index régulier, mais plutôt une extension de ceux-ci dans les circonstances particulières dont ils ont besoin.
Réponses:
Approche très intéressante. Mon vote positif pour la créativité.
Depuis que vous avez récupéré l'espace, je suppose que les index d'origine ne sont plus en place? Les inconvénients des index filtrés sont alors:
En termes pratiques, cela signifie que vous devez être extrêmement prudent avec les index filtrés car ils entraîneront souvent d'horribles plans de requête. Je n'irais pas jusqu'à les qualifier d'inutiles, mais je les considère comme un ajout aux index traditionnels, pas comme un remplacement (comme vous essayez de le faire).
la source
Thomas Kejser répond à ce sujet bien au-dessus.
J'ai juste pensé à ajouter 2 cents.
J'ai vu certains index filtrés uniquement utilisés (affichés dans le plan d'exécution) lorsque vous faites correspondre exactement la clause where de votre requête à celle de l'index filtré.
avez-vous essayé d'utiliser des vues indexées ? colonnes éparses ?
Je crois que dans la mesure où vous n'avez que des articulations internes, vous pouvez créer une vue indexée contenant la ou les clauses where de vos index filtrés, puis vous pouvez utiliser la vue à la place.
Il pourrait y avoir plusieurs vues. Mais comme pour les index non clusterisés, trop nombreux ralentiront votre écriture.
D'après mon expérience, vous auriez de bons gains en lecture, mais vous auriez à surveiller les écritures (insertions et mises à jour) spécialement si les tables sont impliquées dans la réplication.
Cependant, si je comprends bien votre principale préoccupation,
the null values
je vous suggère par conséquent des colonnes SPARSE dans vos index .Les colonnes éparses sont particulièrement appropriées pour les index filtrés
Comme j'ai annoncé des colonnes clairsemées, je ne me sentirais pas bien si je ne vous parlais pas non plus de ses limites:
À la suite de cette
Prenons l'exemple> d'une table qui a 600 colonnes éparses de type bigint.
plus de détails sur le lien ci-dessus, cependant je préfère poster ici aussi cet avertissement:
Le moteur de base de données SQL Server utilise la procédure suivante pour effectuer cette modification:
1 - Ajoute une nouvelle colonne à la table dans la nouvelle taille et le nouveau format de stockage.
2 - Pour chaque ligne du tableau, met à jour et copie la valeur stockée dans l'ancienne colonne vers la nouvelle colonne.
3 - Supprime l'ancienne colonne du schéma de table.
4 - Reconstruit la table (s'il n'y a pas d'index cluster) ou reconstruit l'index cluster pour récupérer l'espace utilisé par l'ancienne colonne.
la source