web-dev-qa-db-fra.com

besoin de suggestions pour améliorer la performance de la vue

Je cherche à améliorer la performance d'une vue sur SQL Server 2008. Cette vue existe dans une base de données de reporting largement utilisée par la non-technicothique-folk pour dénormaliser essentiellement tous ces attributs d'une personne.

C'est une vue très compliquée et longue. Nous avons plus de 19 millions de personnes et il y a beaucoup de logique qui va dans chaque colonne. Par exemple, il existe un indicateur de savoir si une personne est décédée ou non sur trois CTES (expressions de table communes) et une déclaration de cas.

Fondamentalement, c'est un cauchemar.

J'ai besoin de trouver un moyen d'améliorer la performance. Le remplacer sur une table n'est pas possible - les données doivent être exactes à la seconde. Changer à une vue indexée est correct - il utilise des données à partir de plusieurs bases de données. Je ne peux pas vraiment modifier la structure de la colonne car elle briserait un certain nombre de rapports existants.

Y a-t-il des outils dans la boîte à outils qui pourrait aider? Je me demande si des procédures ou des fonctions stockées peuvent vous aider. Peut-être une table avec des colonnes calculées? Je serais en mesure de tirer les informations d'identification de la personne sur une base nocturne et de stocker cela dans une table, mais la grande majorité des colonnes reposent sur des données en direct.

6
JHFB

Les vues ne sont généralement pas implémentées pour la performance. Et bien que vous ne puissiez actuellement pas implémenter des vues indexées explicites (qui ne vient que des vues que SQL Server maintient pour vous), vous pouvez certainement conserver des faits manuellement vous-même.

Par exemple, vous mentionnez que vous calculez actuellement "si une personne est morte ou non" en utilisant trois CTES et une expression de cas (désolé, pour être pédants, ce n'est pas une déclaration).

Au lieu de référencer cet ensemble de CTES à chaque fois la vue, pourquoi ne pas mettre ce fait dans une table (potentiellement avec d'autres faits à calculer par utilisateur) et calculer périodiquement à l'arrière-plan? Donc, peut-être toutes les 5 minutes (c'est juste un swag, vous devrez déterminer ce qui est approprié), vous exécutez un travail d'agent SQL Server qui renonce à la table en fonction de ce qu'il sait actuellement est la vérité. Maintenant, la vue doit simplement faire référence à la table qui est la sortie de ce script, au lieu de le calculer encore et encore lorsque les utilisateurs attendent. Donc, par exemple:

CREATE TABLE dbo.PersonProperties
(
  PersonID INT PRIMARY KEY REFERENCES dbo.Persons(PersonID),
  IsDead BIT NOT NULL DEFAULT 0
);

Maintenant, le travail peut simplement fusionner cette table avec les résultats du CTE, puis la vue peut inclure une référence à ce tableau qui tire simplement la colonne de bits avec une jointure sur la PK. Cela devrait être beaucoup moins coûteux au moment de la requête qui réévaluant toute cette logique à chaque fois.

Pour minimiser le blocage (par exemple, lorsque les utilisateurs accèdent à la vue en même temps, le travail est en cours d'exécution), vous pouvez mettre en œuvre ce que j'appelle "Schema Switch-a-Roo" et que j'ai blogué ici:

http://www.sqlperformance.com/2012/08/t-sql-queries/t-sql-tauxday-schema-switch-a-roo

Donc, au lieu de verrouiller les ressources sur la requête coûteuse tout au long de l'opération, le seul blocage qui se produit est lorsque le commutateur de métadonnées a réellement lieu.


Cela fonctionne aussi longtemps que vous pouvez vous permettre de brèves périodes où les données ne sont pas exactes. Vous pouvez serrer cette fenêtre assez étroite, mais il y a toujours une chance qu'une personne mourra entre et pendant un bref moment, une requête reviendra qu'elle sont toujours vivantes. Si vous ne pouvez pas vous le permettre, vous en faites une partie du processus qui introduit la première fois à la base de données pour vous assurer que le CTE reflète immédiatement et Le nouveau tableau le reflète également immédiatement.

Toujours pas assez bon? Le drapeau d'un utilisateur comme "sale" la seconde une modification d'eux est entré. La vue peut adhérer à un syndicat ou à gauche avec les données stables des utilisateurs qui sont "propres" et vont après des données en direct uniquement pour les utilisateurs "sale".

6
Aaron Bertrand