Meilleure façon de déployer un nouvel index sur une très grande table dans SQL Server 2008

J’ai une base de données en production avec une table qui est devenue extrêmement volumineuse (beaucoup de données accumulées).

Pour améliorer les performances des requêtes, j’ai utilisé l’optimiseur de SQL Server qui a suggéré un nouvel index.

J’ai donc fait une copie de la base de données de production pour tester et cela améliore effectivement les performances, mais mon problème est qu’il a fallu environ 24 heures pour créer l’index et pendant sa création, l’application est inutilisable.

Pour cette application particulière, être hors service quelques heures n’est pas un problème, mais un temps d’arrêt de 24 heures le serait et je cherche un moyen de créer cet index sans avoir à subir cela.

Je n’ai que quelques idées pour le moment.

Une idée est de copier une sauvegarde vers un autre serveur. Appliquer le nouvel index et tout autre changement. Copier la sauvegarde vers le serveur de production. Mettre l’application hors service et fusionner les nouvelles données depuis le moment de la sauvegarde.

Bien sûr, cela a ses propres problèmes comme devoir fusionner les données ensemble, donc je n’aime pas cette idée pour cette raison.

Il s’agit de SQL Server 2008 Standard Ed.

Je déploie normalement les changements de base de données par script.

MISE À JOUR :
Une autre idée serait de déplacer les données d’archive hors de la table principale sur plusieurs jours par morceaux. Puis créer l’index lorsque la table serait devenue suffisamment petite. Puis migrer lentement les données de retour.


Source : Stack Overflow

Si vous utilisiez l’édition Enterprise, vous pourriez utiliser l’option ONLINE de CREATE INDEX qui construit l’index sans maintenir de verrous à long terme sur la table. Il y a des mises en garde concernant son utilisation ; consultez l’article lié pour les détails, et vous pourriez trouver l’impact sur les performances trop important. Mais c’est théorique puisque vous avez dit que vous utilisez l’édition Standard (désolé de l’avoir manqué au début).

Le fait que ce soit une VM fait immédiatement penser à “booster” temporairement la VM ou même à la relocaliser temporairement sur une machine physique maximisée. Pour reconstruire un index sur une très grande table, je pense que la RAM et la vitesse d’E/S seraient les facteurs les plus importants ; la VM utilise-t-elle un disque directement ou un disque virtualisé ? Pouvez-vous temporairement relocaliser les données sur un disque physique ? Ce genre de chose.

Pour information, votre idée de mettre hors ligne et de le faire est exactement ce que je ferais sur une base de données MySQL (je n’ai jamais eu à le faire sur SQL Server) : mettre la base de données principale hors ligne, prendre un instantané, effacer les binlogs/activer le binlogging, et la remettre en marche. Créer l’index sur une machine séparée. Quand c’est prêt, mettre la base de données hors ligne, faire une sauvegarde de la base mise à jour (juste au cas où), remettre l’instantané, appliquer les binlogs et remettre la base en marche. C’est vraiment aussi simple que ça ; je pense que vous pouvez faire la même chose avec SQL Server. Bien sûr, cela suppose que vous pouvez appliquer 24 heures de binlogs contre la table (nouvellement optimisée) dans une fenêtre de temps acceptable !