Longueur utilisée d’une variable SAS : Numérique, Alphanumérique.
Dans la problématique d’optimisation des applications SAS, des traitements et de la charge machine, nous sommes parfois amené à effectuer des recherches afin d’optimiser les programmes SAS et les bases de données SAS.
Un des points important est la volumétrie que représentent ces données. En effet, lorsque des bases de données stockent de grande quantité de données, des dizaines voire des centaines de millions de lignes, il devient très rentable et judicieux de se pencher sur l’optimisation des traitements, programmes SAS, mais également sur les bases de données SAS.
Or si SAS nous fournit une gestion simplifiée de la création et de la gestion de ses tables, il n’en demeure pas moins, qu’un peu de travail d’optimisation reste à la charge du concepteur de l’architecture des données. Cela devient encore plus vrai dans le monde du décisionnel, monde dans lequel les données, stockées sous forme de data Warehouse ou de datamarts, atteignent des volumes très important et ou le temps d’analyse est conséquent.
Hormis les problématiques de bien fondé de telle ou telle variable dans une table, de la normalisation des tables qui n’est pas envisageable dans le BI ou le décisionnel, il nous reste un point important d’optimisation, c’est la longueur de stockage des variables.
Par défaut, les variables SAS, n’ont pas besoin d’être définies, déclarées, leur création est automatiquement effectuée lors de leur assignation de valeur.
Dans le cas d’une définition automatique d’une variable numérique, SAS attribue une longueur par défaut de 8 positions numérique. Or comme vous pouvez le voir ci-dessous dans le tableau présenté (plate-forme MVS/Z/OS), il est bien rare d’avoir besoin d’une si grande longueur de variable.
Table 10.1 Variable Length and Largest Exact Integer Length in Bytes
Significant Digits Retained Largest Integer Represented Exactly
2 2 256
3 4 65,536
4 7 16,777,216
5 9 4,294,967,296
6 12 1,099,511,627,776
7 14 281,474,946,710,656
8 16 72,057,594,037,927,936
SAS nous fournit en standard, via le module SAS Base, un grand nombre de fonctions, telles que : Fonctions de tableaux, fonctions de caractères, fonctions de devises, fonctions de dates et de temps, fonctions de statistiques, fonctions de gestion de fichiers, fonctions financières, fonctions de macro, fonctions mathématiques, fonctions de probabilité de quantile, fonctions aléatoires, fonctions de trigonométrie, fonctions de variable, fonctions de Web …
Or si il est facile pour les variables de type caractères, de connaître la longueur utilisée d’une variable à l’aide de la fonction chaine LENGTH(), il n’en est pas de même pour les variables de type numérique.
Toutefois nous n’allons pas en rester là, et ce que SAS n’a pas fait pour nous, nous allons le faire nous même. Avant de vous donner notre solution, nous allons nous mettre dans un cas d’école simple afin de rappeler le contexte à nos amis débutant en SAS.
Les informaticiens maîtrisant déjà SAS, nous vous conseillons de passer directement à la solution.
Pour les autres, afin de vous aider à mieux comprendre voici un petit programme qui crée une table SAS nommée test_var, en environnement SAS MS Windows.
data test_var;
a=1;
dt='27dec2008'd;
b="un deux";
c=scan(b,1)!!" / "!!scan(b,2)!!".";
run;
Alors à la lecture de ce programme SAS, il serait plausible de penser que :
a : variable numérique longueur 1
dt : variable numérique longueur 9
b : variable alphanumérique longueur 7
c : variable alphanumérique longueur 11, soit b + blanc / blanc et point.
Soit un total pour les lignes de la table de 28 octets, bytes, positions, digit, c …
Eh bien NON !
La longueur totale de la ligne est de 427 c.
Et elle pourrait être réduite à 25 c.
Soit un différentiel de 402 c, ce qui ne représente rien ou pas grand chose pour une table de 200 000 lignes avec si peu de variables, multipliez par 20 le nombre de variable, par 100 le nombre de ligne et alors le gain sera colossale, non seulement en volumétrie, mais lors des traitements de ces données SAS par des programmes, vous économiserez sur le temps de lecture, sur le temps de transfert sur le réseau, sur le volume de mémoire nécessaire, le temps CPU, le temps d’analyse et enfin le temps pour l’écriture des données si vous écrivez une table en sortie.
Voici les explications correspondantes à cette longueur surprenante de 427 c.
- La variable fait 8 position alors que 3 (longueur minimum en environnement MS Windows) aurait suffit
- La variable dt fait 8 alors que 4 aurait suffit (date SAS = nb jours écoulés depuis 1-1-1960).
- La variable b est sans surprise
- En revanche la variable c fait 404 c et là les débutants s’arrachent les cheveux, en fait si vous aviez suivis notre cours SAS de base vous sauriez que par défaut certaines fonctions caractère et notamment la fonction scan, attribue automatique une longueur de 200 c lors de son exécution à la variable résultante.
Voici une variante de solution pour le problème exposé :
data test_var2;
length a 3 dt 4 b $ 7 c $ 11;
a=1;
dt='27dec2008'd;
b="un deux";
c=scan(b,1)!!" / "!!scan(b,2)!!".";
run;
b n’est définit dans l’instruction length, que pour garder l’ordre des variables SAS dans la table test_var2 par rapport à test_var.
Les fonctions : trim(), left(), compress() ne fonctionnement pas pour ce problème (scan). Essayez-le par vous même pour vérifier.
Bien vous vous doutez bien qu’en général, une table SAS ne possède pas qu’une ligne et connue par vous, il va donc falloir mettre au point un petit programme afin de déterminer la longueur maximale utilisée dans notre table.
Pour cela nous allons utiliser la procédure SAS SQL.
Commençons par le plus simple, déterminer la plus grande longueur utilisée d’une variable de type caractère, soit alphanumérique dans une table SAS.
PROC SQL;
select max(length(b)) as lg_b, max(length(c)) as lg_c
from test_var2 ;
Quit ;
Il nous reste maintenant à atteindre le but de cet article d’optimisation SAS, faire la même chose sur les variables numériques, sachant que SAS ne nous proposent pas l’équivalent de LENGTH().
L’astuce est la suivante, calculer le logarithme népérien base 10 des variables et arrondir à l’entier supérieur le résultat obtenu et bien sur ne retenir que la valeur maximale trouvée dans la table. Ajoutons encore une variable à notre table de départ.
data test_var3;
length a 3 dt 4 b $ 7 c $ 11;
a=11;
dt='27dec2008'd;
b="un deux";
c=scan(b,1)!!" / "!!scan(b,2)!!".";
d=123456789;
run;
Et maintenant calculons le résultat :
PROC SQL;
select max(ceil(log10(a))) as lg_a, max(ceil(log10(dt))) as lg_dt, max(ceil(log10(d))) as lg_d
from test_var3 ;
Quit ;
Ici dans notre exemple, la fonction MAX() n’est pas utile, mais elle devient indispensable dans une table de plus d’une ligne.
Le résultat est : 2, 5, 9.
Aidé du tableau des longueurs, dans le companion de votre environnement, vous avez tout pour optimiser les longueur de variable.
A vous de jouer avec SAS!
Au fil du temps et selon notre disponibilité, nous mettrons à votre disposition ces quelques exemples que nous fournissons lors de nos formations SAS.
