Débuter avec SMO et C# : performances SetDefaultInitFields

Bonjour,

Dans l’article précédent, je vous ai montré comment ouvrir une connexion à une instance SQL Server avec SMO et C# puis à lister le nom des bases de données. Avant d’aller plus loin dans l’apprentissage de SMO, il y a une notion très importante à retenir pour avoir de bonnes performances : SetDefaultInitFields.

Si je lance une trace SQL lors de l’exécution du programme qui liste le nom des bases de données, je vais voir que 5 requêtes ont été exécutées. Les 4 premières sont propre à l’utilisation de SMO, il a besoin d’obtenir des informations sur l’instance et la base avant de générer sa requête. Celle qui nous intéresse est la dernière qui sert à lister le nom des bases de données :


SELECT
dtb.name AS [Name]
FROM
master.sys.databases AS dtb
ORDER BY
[Name] ASC

SQL Profiler et SMO

Jusqu’ici, la requête générée est plutôt propre.

Lister la collation de chaque base de données

Je vais un peu modifier le code afin d’ajouter la collation de chaque base de données


string _instanceName = "localhost";
smoCommon.ServerConnection sc = new smoCommon.ServerConnection(_instanceName);
sc.Connect();
smo.Server monServeur = new smo.Server(sc);
foreach (smo.Database maBase in monServeur.Databases)
{
    Console.WriteLine(maBase.Name + " : " + maBase.Collation);
}
sc.Disconnect();

SMO Affichage des bases et des collations

Analyse de la trace SQL Profiler

Voici le résultat de la trace SQL Profiler. Comme vous pouvez le constater, nous sommes loin d’un traitement ensembliste et efficace ! Il y a une seule requête pour récupérer le nom de toutes les bases de données mais ensuite une requête par base de données pour récupérer la collation !

SQL Profiler SMO sans SetDefaultInitFields

Comment rendre le traitement ensembliste ?

Il existe une méthode pour améliorer la génération de l’écriture de la requête. Il s’agit de SetDefaultInitFields. Cette méthode permet de préciser à SMO qu’il doit récupérer certaines ou toutes les propriétés en une seule étape.

Je vais maintenant modifier mon code afin d’utiliser cette méthode pour récupérer également la collation :


string _instanceName = "localhost";
smoCommon.ServerConnection sc = new smoCommon.ServerConnection(_instanceName);
sc.Connect();
smo.Server monServeur = new smo.Server(sc);
monServeur.SetDefaultInitFields(typeof(smo.Database), "Collation");
foreach (smo.Database maBase in monServeur.Databases)
{
 Console.WriteLine(maBase.Name + " : " + maBase.Collation);
}
sc.Disconnect();

Et voici donc le résultat de la trace SQL Profiler.
SQL Profiler SMO avec SetDefaultInitFields

Il n’y a plus qu’une seule requête pour récupérer le nom et la collation :


SELECT
dtb.name AS [Name],
dtb.collation_name AS [Collation],
dtb.name AS [DatabaseName2]
FROM
master.sys.databases AS dtb
ORDER BY
[Name] ASC

Conclusions

Je vous ai montré cette méthode pour les bases de données, mais elle est également valable pour tous les autres objets SMO (les tables, les procédures stockées, les vues, etc…). Imaginez les gains de performance sur une base de données à plusieurs milliers de procédures stockées !

Attention tout de même : si vous écrivez mal la ou les propriétés dans la méthode SetDefaultInitFields, vous n’aurez pas d’erreur à la compilation puisque c’est une stringCollection. L’erreur surviendrait à l’exécution.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Time limit is exhausted. Please reload CAPTCHA.