SAS9

Optimisation SAS : LIBNAME vs SQL Pass-Through pour les grosses volumétries

Simon 22 views
Niveau de difficulté
Débutant
Published on :
Michael

Expert Advice

Michael

Ne passez pas au SQL Pass-Through explicite (CONNECT TO) à l'aveugle ! Avant de sacrifier la portabilité de votre code SAS, activez l'option SASTRACE. Souvent, c'est une simple fonction SAS non traduisible qui bloque le push-down vers la base de données. Identifiez-la, corrigez-la, et laissez le moteur LIBNAME faire le travail lourd sans écrire une ligne de SQL natif

Lorsque vous héritez de codes SAS© effectuant des requêtes complexes (nombreuses jointures, tables de 40 à 100 millions de lignes), la performance devient rapidement le nerf de la guerre. Une question récurrente se pose alors : faut-il utiliser la méthode facile du moteur LIBNAME ou coder en dur via SQL Pass-Through ?

Cet article explore comment diagnostiquer les goulots d'étranglement et choisir la meilleure stratégie pour vos jointures massives.

Le Dilemme : Implicit vs Explicit

Dans SAS©, il existe deux façons principales d'interroger une base de données externe (Oracle, Teradata, SQL Server, etc.) :

  1. LIBNAME (Implicit Pass-Through) : Vous assignez une librairie (libname mydb oracle ...) et vous utilisez les tables comme si elles étaient locales. SAS© tente de traduire votre code SAS© en SQL natif pour l'envoyer à la base de données.

  2. SQL Pass-Through (Explicit Pass-Through) : Vous utilisez CONNECT TO dans une PROC SQL. Vous écrivez le SQL dans le langage de la base de données. SAS© ne fait que "passer le plat" et récupère le résultat final.

Le problème de performance survient souvent avec le LIBNAME lorsque SAS© n'arrive pas à traduire toute la complexité de votre requête (notamment les 8 jointures). Dans ce cas, SAS© télécharge les tables entières (les 40 millions de lignes) sur le serveur SAS© local pour effectuer les jointures lui-même, ce qui explose les temps de traitement et sature le réseau.

Étape 1 : Diagnostiquer avec SASTRACE

Avant de tout réécrire, vous devez voir ce qui se passe "sous le capot". Est-ce que SAS© délègue le travail à la base de données ou rapatrie-t-il les données ?

Activez les options de trace pour voir le SQL généré par le moteur LIBNAME :

1options sastrace=',,,d' sastraceloc=SASLOG;
Si vous voyez une requête SQL complexe avec vos JOIN et WHERE dans le journal : Le moteur LIBNAME fonctionne bien (Implicit Pass-Through réussi). Le problème vient peut-être des index manquants côté base de données.

Si vous voyez des SELECT * FROM table simples : SAS© rapatrie les données brutes pour traiter la jointure en local. C'est ici qu'il faut agir.

Étape 2 : Les Stratégies d'Optimisation

Il n'y a pas de réponse unique, mais voici les pistes à tester, de la plus simple à la plus complexe.

Stratégie A : Forcer le Pass-Through Implicite (LIBNAME)

C'est la méthode à privilégier car elle garde votre code "propre" et portable (indépendant du type de base de données). Si le SASTRACE montre que le travail n'est pas délégué, essayez de simplifier la syntaxe SAS© ou d'utiliser des fonctions compatibles avec votre SGBD pour aider SAS© à traduire la requête.

Stratégie B : Passer en Pass-Through Explicite

Si le moteur LIBNAME échoue à optimiser, écrivez la requête directement en SQL natif via CONNECT TO.

  • Avantage : Vous garantissez que le travail lourd (jointures, tris) est fait par le serveur de base de données, qui est souvent plus puissant que le serveur SAS©.

  • Inconvénient : Vous perdez la portabilité (le code devient spécifique à Oracle/SQL Server/etc.).

1PROC SQL;
2 connect to oracle (user=... password=... path=...);
3 create TABLE want as
4 select * from connection to oracle
5 (
6 SELECT A.id, B.value
7 FROM tableA A
8 INNER JOIN tableB B ON A.id = B.id
9 /* Ce code est exécuté par Oracle, pas SAS */
10 );
11 disconnect from oracle;
12QUIT;

Stratégie C : L'approche hybride (SAS© natif)

Contre-intuitivement, il arrive que les bases de données soient moins performantes que SAS© pour certaines opérations, ou que le réseau soit trop lent pour remonter le résultat d'une jointure complexe.

Une alternative solide consiste à :

  1. Extraire uniquement les colonnes nécessaires de chaque table vers des tables temporaires SAS© (Subsetting).

  2. Utiliser PROC SORT et DATA STEP MERGE en local.

Le moteur de tri de SAS© est extrêmement performant. Sur des volumes massifs, un MERGE bien préparé peut parfois battre une requête SQL mal indexée côté serveur.

Étape 3 : Mesurer la performance

Ne vous fiez pas à votre montre. Utilisez les outils de benchmarking intégrés pour comparer vos tests (LIBNAME vs Pass-Through vs Data Step) :

  1. options FULLSTIMER; : Affiche dans le journal le temps CPU, le temps réel et la mémoire utilisée pour chaque étape.

  2. PROC SQL _method; : Si vous restez en SAS© pur, cette option vous montre l'algorithme utilisé par SAS© (Hash Join, Sort Merge Join, etc.) pour exécuter la requête.

Il n'y a pas de magie, seulement des tests comparatifs (FULLSTIMER) dans votre environnement spécifique.

Pour optimiser vos jointures massives :

  1. Auditez d'abord avec SASTRACE pour voir si le LIBNAME fait son travail.

  2. Testez le Pass-Through explicite si le implicite échoue.

  3. N'écartez pas l'option de rapatrier des sous-ensembles de données pour faire un MERGE local si le serveur de base de données est surchargé.